[cfe-commits] r70805 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/Sema/SemaExpr.cpp test/Sema/deref.c test/Sema/varargs.c

Eli Friedman eli.friedman at gmail.com
Sun May 3 15:36:05 PDT 2009


Author: efriedma
Date: Sun May  3 17:36:05 2009
New Revision: 70805

URL: http://llvm.org/viewvc/llvm-project?rev=70805&view=rev
Log:
PR2524: downgrade taking address of expression of type 'void' to an 
extension warning.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/deref.c
    cfe/trunk/test/Sema/varargs.c

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=70805&r1=70804&r2=70805&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sun May  3 17:36:05 2009
@@ -147,6 +147,9 @@
     LV_MemberFunction
   };
   isLvalueResult isLvalue(ASTContext &Ctx) const;
+
+  // Same as above, but excluding checks for non-object and void types in C
+  isLvalueResult isLvalueInternal(ASTContext &Ctx) const;
   
   /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
   /// does not have an incomplete type, does not have a const-qualified type,

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=70805&r1=70804&r2=70805&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun May  3 17:36:05 2009
@@ -1021,6 +1021,8 @@
 def err_static_block_func : Error<
   "function declared in block scope cannot have 'static' storage class">;
 def err_typecheck_address_of : Error<"address of %0 requested">;
+def ext_typecheck_addrof_void : Extension<
+  "ISO C forbids taking the address of an expression of type 'void'">;
 def err_typecheck_invalid_lvalue_addrof : Error<
   "address expression must be an lvalue or a function designator">;
 def err_typecheck_unary_expr : Error<

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=70805&r1=70804&r2=70805&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sun May  3 17:36:05 2009
@@ -603,18 +603,26 @@
 ///  - 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 @@
     return LV_Valid;
   case PredefinedExprClass:
     return LV_Valid;
-  case VAArgExprClass:
-    return LV_NotObjectType;
   case CXXDefaultArgExprClass:
     return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
   case CXXConditionDeclExprClass:

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=70805&r1=70804&r2=70805&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun May  3 17:36:05 2009
@@ -4245,7 +4245,12 @@
 
   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();

Modified: cfe/trunk/test/Sema/deref.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/deref.c?rev=70805&r1=70804&r2=70805&view=diff

==============================================================================
--- cfe/trunk/test/Sema/deref.c (original)
+++ cfe/trunk/test/Sema/deref.c Sun May  3 17:36:05 2009
@@ -1,4 +1,5 @@
-// RUN: clang-cc -fsyntax-only -verify -std=c90 %s
+/* RUN: clang-cc -fsyntax-only -verify -std=c90 -pedantic %s
+ */
 void
 foo (void)
 {
@@ -17,7 +18,7 @@
 void foo3 (void)
 {
  void* x = 0;
- void* y = &*x; // expected-error{{address expression must be an lvalue or a function designator}}
+ void* y = &*x; /* expected-warning{{address of an expression of type 'void'}} */
 }
 
 extern const void cv1;
@@ -30,7 +31,7 @@
 extern void cv2;
 void *foo5 (void)
 {
-  return &cv2; // expected-error{{address expression must be an lvalue or a function designator}}
+  return &cv2; /* expected-warning{{address of an expression of type 'void'}} */
 }
 
 typedef const void CVT;

Modified: cfe/trunk/test/Sema/varargs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/varargs.c?rev=70805&r1=70804&r2=70805&view=diff

==============================================================================
--- cfe/trunk/test/Sema/varargs.c (original)
+++ cfe/trunk/test/Sema/varargs.c Sun May  3 17:36:05 2009
@@ -56,7 +56,7 @@
   __builtin_va_list ap;
   __builtin_va_start(ap, a);
   // FIXME: This error message is sub-par.
-  __builtin_va_arg(ap, int) = 1; // expected-error {{non-object type 'int' is not assignable}}
+  __builtin_va_arg(ap, int) = 1; // expected-error {{expression is not assignable}}
   int *x = &__builtin_va_arg(ap, int); // expected-error {{address expression must be an lvalue or a function designator}}
   __builtin_va_end(ap);
 }





More information about the cfe-commits mailing list