зеркало из https://github.com/microsoft/clang-1.git
Give OpaqueValueExpr a source location, because its source location
might be queried in places where we absolutely require a valid location (e.g., for template instantiation). Fixes some major brokenness in the use of __is_convertible_to. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124465 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
70a21de5b4
Коммит
b608b98771
|
@ -3625,15 +3625,22 @@ public:
|
|||
/// context.
|
||||
class OpaqueValueExpr : public Expr {
|
||||
friend class ASTStmtReader;
|
||||
SourceLocation Loc;
|
||||
|
||||
public:
|
||||
OpaqueValueExpr(QualType T, ExprValueKind VK, ExprObjectKind OK = OK_Ordinary)
|
||||
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
|
||||
ExprObjectKind OK = OK_Ordinary)
|
||||
: Expr(OpaqueValueExprClass, T, VK, OK,
|
||||
T->isDependentType(), T->isDependentType(), false) {
|
||||
T->isDependentType(), T->isDependentType(), false),
|
||||
Loc(Loc) {
|
||||
}
|
||||
|
||||
explicit OpaqueValueExpr(EmptyShell Empty)
|
||||
: Expr(OpaqueValueExprClass, Empty) { }
|
||||
|
||||
/// \brief Retrieve the location of this expression.
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
|
||||
virtual SourceRange getSourceRange() const;
|
||||
virtual child_iterator child_begin();
|
||||
virtual child_iterator child_end();
|
||||
|
|
|
@ -4551,7 +4551,8 @@ public:
|
|||
/// CheckAssignmentConstraints - Perform type checking for assignment,
|
||||
/// argument passing, variable initialization, and function return values.
|
||||
/// C99 6.5.16.
|
||||
AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
|
||||
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc,
|
||||
QualType lhs, QualType rhs);
|
||||
|
||||
/// Check assignment constraints and prepare for a conversion of the
|
||||
/// RHS to the LHS type.
|
||||
|
|
|
@ -2981,7 +2981,7 @@ Stmt::child_iterator BlockDeclRefExpr::child_begin() { return child_iterator();}
|
|||
Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator(); }
|
||||
|
||||
// OpaqueValueExpr
|
||||
SourceRange OpaqueValueExpr::getSourceRange() const { return SourceRange(); }
|
||||
SourceRange OpaqueValueExpr::getSourceRange() const { return Loc; }
|
||||
Stmt::child_iterator OpaqueValueExpr::child_begin() { return child_iterator(); }
|
||||
Stmt::child_iterator OpaqueValueExpr::child_end() { return child_iterator(); }
|
||||
|
||||
|
|
|
@ -1472,7 +1472,8 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
|||
// If this ever proves to be a problem it should be easy to fix.
|
||||
QualType Ty = S.Context.getPointerType(VD->getType());
|
||||
QualType ParamTy = FD->getParamDecl(0)->getType();
|
||||
if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
|
||||
if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
|
||||
ParamTy, Ty) != Sema::Compatible) {
|
||||
S.Diag(Attr.getParameterLoc(),
|
||||
diag::err_attribute_cleanup_func_arg_incompatible_type) <<
|
||||
Attr.getParameterName() << ParamTy << Ty;
|
||||
|
|
|
@ -5507,12 +5507,13 @@ Sema::CheckObjCPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
|
|||
}
|
||||
|
||||
Sema::AssignConvertType
|
||||
Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
||||
Sema::CheckAssignmentConstraints(SourceLocation Loc,
|
||||
QualType lhsType, QualType rhsType) {
|
||||
// Fake up an opaque expression. We don't actually care about what
|
||||
// cast operations are required, so if CheckAssignmentConstraints
|
||||
// adds casts to this they'll be wasted, but fortunately that doesn't
|
||||
// usually happen on valid code.
|
||||
OpaqueValueExpr rhs(rhsType, VK_RValue);
|
||||
OpaqueValueExpr rhs(Loc, rhsType, VK_RValue);
|
||||
Expr *rhsPtr = &rhs;
|
||||
CastKind K = CK_Invalid;
|
||||
|
||||
|
@ -6952,7 +6953,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
|
|||
}
|
||||
} else {
|
||||
// Compound assignment "x += y"
|
||||
ConvTy = CheckAssignmentConstraints(LHSType, RHSType);
|
||||
ConvTy = CheckAssignmentConstraints(Loc, LHSType, RHSType);
|
||||
}
|
||||
|
||||
if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType,
|
||||
|
|
|
@ -2531,7 +2531,7 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
|
|||
LhsT = Self.Context.getRValueReferenceType(LhsT);
|
||||
|
||||
InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT));
|
||||
OpaqueValueExpr From(LhsT.getNonLValueExprType(Self.Context),
|
||||
OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
|
||||
Expr::getValueKindForType(LhsT));
|
||||
Expr *FromPtr = &From;
|
||||
InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc,
|
||||
|
|
|
@ -440,9 +440,13 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
|||
Context.canAssignObjCInterfaces(
|
||||
PropType->getAs<ObjCObjectPointerType>(),
|
||||
IvarType->getAs<ObjCObjectPointerType>());
|
||||
else
|
||||
compat = (CheckAssignmentConstraints(PropType, IvarType)
|
||||
else {
|
||||
SourceLocation Loc = PropertyIvarLoc;
|
||||
if (Loc.isInvalid())
|
||||
Loc = PropertyLoc;
|
||||
compat = (CheckAssignmentConstraints(Loc, PropType, IvarType)
|
||||
== Compatible);
|
||||
}
|
||||
if (!compat) {
|
||||
Diag(PropertyLoc, diag::error_property_ivar_type)
|
||||
<< property->getDeclName() << PropType
|
||||
|
@ -663,7 +667,7 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
|
|||
GetterMethod->getResultType() != property->getType()) {
|
||||
AssignConvertType result = Incompatible;
|
||||
if (property->getType()->isObjCObjectPointerType())
|
||||
result = CheckAssignmentConstraints(GetterMethod->getResultType(),
|
||||
result = CheckAssignmentConstraints(Loc, GetterMethod->getResultType(),
|
||||
property->getType());
|
||||
if (result != Compatible) {
|
||||
Diag(Loc, diag::warn_accessor_property_type_mismatch)
|
||||
|
|
|
@ -1327,6 +1327,7 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
|
|||
|
||||
void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->Loc = ReadSourceLocation(Record, Idx);
|
||||
}
|
||||
|
||||
Stmt *ASTReader::ReadStmt(PerFileData &F) {
|
||||
|
|
|
@ -1332,6 +1332,7 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
|
|||
|
||||
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
||||
VisitExpr(E);
|
||||
Writer.AddSourceLocation(E->getLocation(), Record);
|
||||
Code = serialization::EXPR_OPAQUE_VALUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -508,6 +508,11 @@ class PrivateCopy {
|
|||
friend void is_convertible_to();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct X0 {
|
||||
template<typename U> X0(const X0<U>&);
|
||||
};
|
||||
|
||||
void is_convertible_to() {
|
||||
int t01[T(__is_convertible_to(Int, Int))];
|
||||
int t02[F(__is_convertible_to(Int, IntAr))];
|
||||
|
@ -531,4 +536,5 @@ void is_convertible_to() {
|
|||
int t20[F(__is_convertible_to(const IntAr&, IntAr&))];
|
||||
int t21[F(__is_convertible_to(Function, Function))];
|
||||
int t22[F(__is_convertible_to(PrivateCopy, PrivateCopy))];
|
||||
int t23[T(__is_convertible_to(X0<int>, X0<float>))];
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче