diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 7 |
2 files changed, 17 insertions, 6 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 19d67bb7f8a..13d2a1be3f9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -603,18 +603,26 @@ static bool DeclCanBeLvalue(const NamedDecl *Decl, ASTContext &Ctx) { /// - reference type [C++ [expr]] /// Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const { + assert(!TR->isReferenceType() && "Expressions can't have reference type."); + + isLvalueResult Res = isLvalueInternal(Ctx); + if (Res != LV_Valid || Ctx.getLangOptions().CPlusPlus) + return Res; + // first, check the type (C99 6.3.2.1). Expressions with function // type in C are not lvalues, but they can be lvalues in C++. - if (!Ctx.getLangOptions().CPlusPlus && TR->isFunctionType()) + if (TR->isFunctionType()) return LV_NotObjectType; // Allow qualified void which is an incomplete type other than void (yuck). if (TR->isVoidType() && !Ctx.getCanonicalType(TR).getCVRQualifiers()) return LV_IncompleteVoidType; - assert(!TR->isReferenceType() && "Expressions can't have reference type."); + return LV_Valid; +} - // the type looks fine, now check the expression +// Check whether the expression can be sanely treated like an l-value +Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { switch (getStmtClass()) { case StringLiteralClass: // C99 6.5.1p4 case ObjCEncodeExprClass: // @encode behaves like its string in every way. @@ -754,8 +762,6 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const { return LV_Valid; case PredefinedExprClass: return LV_Valid; - case VAArgExprClass: - return LV_NotObjectType; case CXXDefaultArgExprClass: return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx); case CXXConditionDeclExprClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6ce98cd28f7..36ec9c65c13 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4245,7 +4245,12 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { if (lval != Expr::LV_Valid) { // C99 6.5.3.2p1 // The operand must be either an l-value or a function designator - if (!op->getType()->isFunctionType()) { + if (op->getType()->isFunctionType()) { + // Function designator is valid + } else if (lval == Expr::LV_IncompleteVoidType) { + Diag(OpLoc, diag::ext_typecheck_addrof_void) + << op->getSourceRange(); + } else { // FIXME: emit more specific diag... Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) << op->getSourceRange(); |

