summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp16
-rw-r--r--clang/lib/Sema/SemaExpr.cpp7
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();
OpenPOWER on IntegriCloud