]> granicus.if.org Git - clang/commitdiff
First pass at implementing the intent of ANSI C DR106.
authorJohn McCall <rjmccall@apple.com>
Sat, 4 Dec 2010 12:29:11 +0000 (12:29 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 4 Dec 2010 12:29:11 +0000 (12:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120904 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
test/CodeGen/exprs.c

index cf17566d41a6ace3781905361295ab738af1f1ec..3d6d59a406a55f92f1ecfc4b0c821d3f6e2d02b2 100644 (file)
@@ -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
index fc396b992f47a72da45623e15dbb50f944e7d251..eec2fc88db6340c2c8c2620f4dc7ff84566cb358 100644 (file)
@@ -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) {
index c9978b85164218d2adcf98941f5463f6d66e552f..452c823d15fb04466e3ff36aa6daef6237027a2f 100644 (file)
@@ -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
+}