]> granicus.if.org Git - clang/commitdiff
The control expression for a _Generic selection expression should have
authorAaron Ballman <aaron@aaronballman.com>
Thu, 5 Nov 2015 00:06:05 +0000 (00:06 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Thu, 5 Nov 2015 00:06:05 +0000 (00:06 +0000)
its type decayed and qualifiers stripped when determining which
selection it matches. Fixes PR16340.

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

lib/Sema/SemaExpr.cpp
test/Sema/generic-selection.c

index 857925da99c08def86646066ac1c246a2663de4c..a4ca8a065cb41f82cb0d1e48b7cd7f6b7541c278 100644 (file)
@@ -1354,11 +1354,13 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
                                  ArrayRef<Expr *> Exprs) {
   unsigned NumAssocs = Types.size();
   assert(NumAssocs == Exprs.size());
-  if (ControllingExpr->getType()->isPlaceholderType()) {
-    ExprResult result = CheckPlaceholderExpr(ControllingExpr);
-    if (result.isInvalid()) return ExprError();
-    ControllingExpr = result.get();
-  }
+
+  // Decay and strip qualifiers for the controlling expression type, and handle
+  // placeholder type replacement. See committee discussion from WG14 DR423.
+  ExprResult R = DefaultFunctionArrayLvalueConversion(ControllingExpr);
+  if (R.isInvalid())
+    return ExprError();
+  ControllingExpr = R.get();
 
   // The controlling expression is an unevaluated operand, so side effects are
   // likely unintended.
index 8cef975c709c851b92c408b6b2555c82e79b2bea..0563ec0f4fc002ba9636a177148afe9c7140d662 100644 (file)
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s
 
+void g(void);
+
 void foo(int n) {
   (void) _Generic(0,
       struct A: 0, // expected-error {{type 'struct A' in generic association incomplete}}
@@ -23,4 +25,10 @@ void foo(int n) {
   int a4[_Generic(0L, default: 1, short: 2, float: 3, int: 4) == 1 ? 1 : -1];
   int a5[_Generic(0, int: 1, short: 2, float: 3) == 1 ? 1 : -1];
   int a6[_Generic(0, short: 1, float: 2, int: 3) == 3 ? 1 : -1];
+
+  int a7[_Generic("test", char *: 1, default: 2) == 1 ? 1 : -1];
+  int a8[_Generic(g, void (*)(void): 1, default: 2) == 1 ? 1 : -1];
+
+  const int i = 12;
+  int a9[_Generic(i, int: 1, default: 2) == 1 ? 1 : -1];
 }