From: John McCall Date: Sat, 4 Dec 2010 12:29:11 +0000 (+0000) Subject: First pass at implementing the intent of ANSI C DR106. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=85515d64c15838eadb3ffe82b635f8217b04be8a;p=clang First pass at implementing the intent of ANSI C DR106. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120904 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index cf17566d41..3d6d59a406 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -269,6 +269,13 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) { T->isRecordType())) return; + // The C standard is actually really unclear on this point, and + // DR106 tells us what the result should be but not why. It's + // generally best to say that void just doesn't undergo + // lvalue-to-rvalue at all. + if (T->isVoidType()) + return; + // C++ [conv.lval]p1: // [...] If T is a non-class type, the type of the prvalue is the // cv-unqualified version of T. Otherwise, the type of the diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index fc396b992f..eec2fc88db 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3549,8 +3549,9 @@ void Sema::IgnoredValueConversions(Expr *&E) { } DefaultFunctionArrayLvalueConversion(E); - RequireCompleteType(E->getExprLoc(), E->getType(), - diag::err_incomplete_type); + if (!E->getType()->isVoidType()) + RequireCompleteType(E->getExprLoc(), E->getType(), + diag::err_incomplete_type); } ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) { diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index c9978b8516..452c823d15 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -147,8 +147,22 @@ double f13(double X) { } // Check operations on incomplete types. -struct s14; -void f14(struct s13 *a) { +void f14(struct s14 *a) { (void) &*a; } +// CHECK: define void @f15 +void f15(void *v, const void *cv, volatile void *vv) { + extern void f15_helper(void); + f15_helper(); + // CHECK: call void @f15_helper() + // FIXME: no loads from i8* should occur here at all! + *v; *v, *v; v ? *v : *v; + *cv; *cv, *cv; v ? *cv : *cv; + *vv; *vv, *vv; vv ? *vv : *vv; + // CHECK: volatile load i8* + // CHECK: volatile load i8* + // CHECK: volatile load i8* + // CHECK-NOT: load i8* % + // CHECK: ret void +}