Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -608,7 +608,7 @@ EmitStmt(S.getInit()); if (S.getConditionVariable()) - EmitAutoVarDecl(*S.getConditionVariable()); + EmitDecl(*S.getConditionVariable()); // If the condition constant folds and can be elided, try to avoid emitting // the condition and the dead arm of the if/else. @@ -705,7 +705,7 @@ RunCleanupsScope ConditionScope(*this); if (S.getConditionVariable()) - EmitAutoVarDecl(*S.getConditionVariable()); + EmitDecl(*S.getConditionVariable()); // Evaluate the conditional in the while header. C99 6.8.5.1: The // evaluation of the controlling expression takes place before each @@ -865,7 +865,7 @@ // If the for statement has a condition scope, emit the local variable // declaration. if (S.getConditionVariable()) { - EmitAutoVarDecl(*S.getConditionVariable()); + EmitDecl(*S.getConditionVariable()); } llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); @@ -1574,7 +1574,7 @@ // Emit the condition variable if needed inside the entire cleanup scope // used by this special case for constant folded switches. if (S.getConditionVariable()) - EmitAutoVarDecl(*S.getConditionVariable()); + EmitDecl(*S.getConditionVariable()); // At this point, we are no longer "within" a switch instance, so // we can temporarily enforce this to ensure that any embedded case @@ -1603,7 +1603,7 @@ EmitStmt(S.getInit()); if (S.getConditionVariable()) - EmitAutoVarDecl(*S.getConditionVariable()); + EmitDecl(*S.getConditionVariable()); llvm::Value *CondV = EmitScalarExpr(S.getCond()); // Create basic block to hold stuff that comes after switch Index: test/Parser/decomposed-condition.cpp =================================================================== --- test/Parser/decomposed-condition.cpp +++ test/Parser/decomposed-condition.cpp @@ -1,5 +1,20 @@ // RUN: %clang_cc1 -std=c++1z %s -verify +namespace std { + template struct tuple_size; + template struct tuple_element; +} + +struct Get { + template int get() { return 0; } + operator bool() { return true; } +}; + +namespace std { + template<> struct tuple_size { static constexpr int value = 1; }; + template<> struct tuple_element<0, Get> { using type = int; }; +} + struct Na { bool flag; float data; @@ -17,29 +32,35 @@ Na g(); namespace CondInIf { -void h() { +int h() { if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} ; if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}} ; + if (auto [value] = Get()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} + return value; } } // namespace CondInIf namespace CondInWhile { -void h() { +int h() { while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} ; while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}} ; + while (auto [value] = Get()) // expected-warning{{ISO C++17 does not permit structured binding declaration in a condition}} + return value; } } // namespace CondInWhile namespace CondInFor { -void h() { +int h() { for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} ; for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}} ; + for (; auto [value] = Get();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} + return value; } } // namespace CondInFor @@ -52,10 +73,15 @@ }; namespace CondInSwitch { -void h(IntegerLike x) { +int h(IntegerLike x) { switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} ; switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}} ; + switch (auto [value] = Get()) {// expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} + // expected-warning@-1{{switch condition has boolean value}} + case 1: + return value; + } } } // namespace CondInSwitch