]> granicus.if.org Git - clang/commitdiff
Add a new expression classification, CL_AddressableVoid
authorPeter Collingbourne <peter@pcc.me.uk>
Tue, 19 Apr 2011 18:51:51 +0000 (18:51 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Tue, 19 Apr 2011 18:51:51 +0000 (18:51 +0000)
CL_AddressableVoid is the expression classification used for void
expressions whose address can be taken, i.e. the result of [], *
or void variable references in C, as opposed to things like the
result of a void function call.

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

include/clang/AST/Expr.h
lib/AST/ExprClassification.cpp
test/Sema/expr-address-of.c

index 472de76eb87ee5260ed961235b45baf828c14caa..6b616c28b39fff088138618e8c982b63f4974263 100644 (file)
@@ -221,6 +221,7 @@ public:
       CL_XValue,
       CL_Function, // Functions cannot be lvalues in C.
       CL_Void, // Void cannot be an lvalue in C.
+      CL_AddressableVoid, // Void expression whose address can be taken in C.
       CL_DuplicateVectorComponents, // A vector shuffle with dupes.
       CL_MemberFunction, // An expression referring to a member function
       CL_SubObjCPropertySetting,
index 803bc561bae67e84ed59d4944e0197e2d3eb19ca..0d018804143e2bb925a4730e62502cb566120bf9 100644 (file)
@@ -61,8 +61,10 @@ Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
     if (TR->isFunctionType() || TR == Ctx.OverloadTy)
       kind = Cl::CL_Function;
     // No void either, but qualified void is OK because it is "other than void".
-    else if (TR->isVoidType() && !Ctx.getCanonicalType(TR).hasQualifiers())
-      kind = Cl::CL_Void;
+    // Void "lvalues" are classified as addressable void values, which are void
+    // expressions whose address can be taken.
+    else if (TR->isVoidType() && !TR.hasQualifiers())
+      kind = (kind == Cl::CL_LValue ? Cl::CL_AddressableVoid : Cl::CL_Void);
   }
 
   // Enable this assertion for testing.
@@ -71,6 +73,7 @@ Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
   case Cl::CL_XValue: assert(getValueKind() == VK_XValue); break;
   case Cl::CL_Function:
   case Cl::CL_Void:
+  case Cl::CL_AddressableVoid:
   case Cl::CL_DuplicateVectorComponents:
   case Cl::CL_MemberFunction:
   case Cl::CL_SubObjCPropertySetting:
@@ -563,7 +566,8 @@ Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const {
   case Cl::CL_LValue: return LV_Valid;
   case Cl::CL_XValue: return LV_InvalidExpression;
   case Cl::CL_Function: return LV_NotObjectType;
-  case Cl::CL_Void: return LV_IncompleteVoidType;
+  case Cl::CL_Void: return LV_InvalidExpression;
+  case Cl::CL_AddressableVoid: return LV_IncompleteVoidType;
   case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents;
   case Cl::CL_MemberFunction: return LV_MemberFunction;
   case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting;
@@ -582,7 +586,8 @@ Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
   case Cl::CL_LValue: break;
   case Cl::CL_XValue: return MLV_InvalidExpression;
   case Cl::CL_Function: return MLV_NotObjectType;
-  case Cl::CL_Void: return MLV_IncompleteVoidType;
+  case Cl::CL_Void: return MLV_InvalidExpression;
+  case Cl::CL_AddressableVoid: return MLV_IncompleteVoidType;
   case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
   case Cl::CL_MemberFunction: return MLV_MemberFunction;
   case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
index 8f9f795d00ddff4f99066b2a1b3c577fe557fcc1..2b8cfbfa68f59cf8c9b4b046da3a53f90f30ee48 100644 (file)
@@ -107,3 +107,14 @@ char* f7() {
 
   void* t3 = &(*(void*)0);
 }
+
+void f8() {
+  void *dummy0 = &f8(); // expected-error {{address expression must be an lvalue or a function designator}}
+
+  extern void v;
+  void *dummy1 = &(1 ? v : f8()); // expected-error {{address expression must be an lvalue or a function designator}}
+
+  void *dummy2 = &(f8(), v); // expected-error {{address expression must be an lvalue or a function designator}}
+
+  void *dummy3 = &({ ; }); // expected-error {{address expression must be an lvalue or a function designator}}
+}