From 1c860d5640e8eebb11a5d515a761242b66761b0b Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 19 Apr 2011 18:51:51 +0000 Subject: [PATCH] Add a new expression classification, CL_AddressableVoid 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 | 1 + lib/AST/ExprClassification.cpp | 13 +++++++++---- test/Sema/expr-address-of.c | 11 +++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 472de76eb8..6b616c28b3 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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, diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 803bc561ba..0d01880414 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -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; diff --git a/test/Sema/expr-address-of.c b/test/Sema/expr-address-of.c index 8f9f795d00..2b8cfbfa68 100644 --- a/test/Sema/expr-address-of.c +++ b/test/Sema/expr-address-of.c @@ -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}} +} -- 2.40.0