]> granicus.if.org Git - clang/commitdiff
Refactor address-of-void extension a bit so that it's more obviously
authorEli Friedman <eli.friedman@gmail.com>
Sat, 16 May 2009 23:27:50 +0000 (23:27 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sat, 16 May 2009 23:27:50 +0000 (23:27 +0000)
correct.  No functionality change, as far as I know.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71965 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp

index a31a96488ac024017802199926ee811656d65886..744b020986019c25fc49c5d1bc2237641712816b 100644 (file)
@@ -4426,14 +4426,10 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
   NamedDecl *dcl = getPrimaryDecl(op);
   Expr::isLvalueResult lval = op->isLvalue(Context);
 
-  if (lval != Expr::LV_Valid) { // C99 6.5.3.2p1
+  if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
+    // C99 6.5.3.2p1
     // The operand must be either an l-value or a function designator
-    if (op->getType()->isFunctionType()) {
-      // Function designator is valid
-    } else if (lval == Expr::LV_IncompleteVoidType) {
-      Diag(OpLoc, diag::ext_typecheck_addrof_void)
-        << op->getSourceRange();
-    } else {
+    if (!op->getType()->isFunctionType()) {
       // FIXME: emit more specific diag...
       Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof)
         << op->getSourceRange();
@@ -4481,6 +4477,13 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
       assert(0 && "Unknown/unexpected decl type");
   }
 
+  if (lval == Expr::LV_IncompleteVoidType) {
+    // Taking the address of a void variable is technically illegal, but we
+    // allow it in cases which are otherwise valid.
+    // Example: "extern void x; void* y = &x;".
+    Diag(OpLoc, diag::ext_typecheck_addrof_void) << op->getSourceRange();
+  }
+
   // If the operand has type "type", the result has type "pointer to type".
   return Context.getPointerType(op->getType());
 }