diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-02-02 02:14:45 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-02-02 02:14:45 +0000 |
commit | c084bd2888153084cf8bc8c0337a88cf2ab53e8c (patch) | |
tree | 7a0da883040e315449c4c1c6c25f5d26b0dc660d /clang/lib/Sema/SemaExpr.cpp | |
parent | 4be2c3692112a841f1baf606bf4fcfaff163c2cb (diff) | |
download | bcm5719-llvm-c084bd2888153084cf8bc8c0337a88cf2ab53e8c.tar.gz bcm5719-llvm-c084bd2888153084cf8bc8c0337a88cf2ab53e8c.zip |
PR15132: Replace "address expression must be an lvalue or a function
designator" diagnostic with more correct and more human-friendly "cannot take
address of rvalue of type 'T'".
For the case of & &T::f, provide a custom diagnostic, rather than unhelpfully
saying "cannot take address of rvalue of type '<overloaded function type>'".
For the case of &array_temporary, treat it just like a class temporary
(including allowing it as an extension); the existing diagnostic wording
for the class temporary case works fine.
llvm-svn: 174262
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0465707e7c0..ef852d354ff 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8033,7 +8033,9 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, if (const BuiltinType *PTy = OrigOp.get()->getType()->getAsPlaceholderType()){ if (PTy->getKind() == BuiltinType::Overload) { if (!isa<OverloadExpr>(OrigOp.get()->IgnoreParens())) { - S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) + assert(cast<UnaryOperator>(OrigOp.get()->IgnoreParens())->getOpcode() + == UO_AddrOf); + S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof_addrof_function) << OrigOp.get()->getSourceRange(); return QualType(); } @@ -8077,10 +8079,10 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, Expr::LValueClassification lval = op->ClassifyLValue(S.Context); unsigned AddressOfError = AO_No_Error; - if (lval == Expr::LV_ClassTemporary) { + if (lval == Expr::LV_ClassTemporary || lval == Expr::LV_ArrayTemporary) { bool sfinae = S.isSFINAEContext(); - S.Diag(OpLoc, sfinae ? diag::err_typecheck_addrof_class_temporary - : diag::ext_typecheck_addrof_class_temporary) + S.Diag(OpLoc, sfinae ? diag::err_typecheck_addrof_temporary + : diag::ext_typecheck_addrof_temporary) << op->getType() << op->getSourceRange(); if (sfinae) return QualType(); @@ -8128,9 +8130,8 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, if (isa<PseudoObjectExpr>(op)) { AddressOfError = AO_Property_Expansion; } else { - // FIXME: emit more specific diag... S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) - << op->getSourceRange(); + << op->getType() << op->getSourceRange(); return QualType(); } } |