The control expression for a _Generic selection expression should have
its type decayed and qualifiers stripped when determining which selection it matches. Fixes PR16340. llvm-svn: 252104
This commit is contained in:
parent
e5739981d5
commit
b035cd7ea4
|
@ -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.
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue