Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5140,12 +5140,18 @@ // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = - TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, + /*AllowObjcWritebackConversion=*/false, + /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Index: test/CodeGenCXX/cxx1z-constexpr-if.cpp =================================================================== --- test/CodeGenCXX/cxx1z-constexpr-if.cpp +++ test/CodeGenCXX/cxx1z-constexpr-if.cpp @@ -1,8 +1,17 @@ // RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used +// RUN: %clang_cc1 -std=c++1z %s -DCHECK_CONVERSION -verify %s void should_be_used_1(); void should_be_used_2(); +void should_be_used_3(); void should_not_be_used(); + +struct A { + constexpr explicit operator bool() const { + return true; + } +}; + void f() { if constexpr (false) should_not_be_used(); @@ -15,7 +24,17 @@ goto foo; foo: should_not_be_used(); } + if constexpr (A()) + should_be_used_3(); + else + should_not_be_used(); +#ifdef CHECK_CONVERSION + if constexpr (4.3) ; // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} + constexpr void *p = nullptr; + if constexpr (p) ; // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}} +#endif } // CHECK: should_be_used_1 // CHECK: should_be_used_2 +// CHECK: should_be_used_3