From f602806965531ee06fd8664b9d7a8912c4af2870 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 23 Mar 2012 23:55:39 +0000 Subject: [PATCH] Teach APValue printer to print boolean 0 and 1 as 'false' and 'true'. Fix up some calling code to actually pass in a non-null type, to avoid a crash. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153358 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Overload.h | 3 ++- lib/AST/APValue.cpp | 5 ++++- lib/Sema/SemaInit.cpp | 6 ++++-- lib/Sema/SemaOverload.cpp | 20 +++++++++++++++----- test/SemaCXX/constexpr-printing.cpp | 4 ++++ 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 1d53faaa2d..d334447edc 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -236,7 +236,8 @@ namespace clang { ImplicitConversionRank getRank() const; NarrowingKind getNarrowingKind(ASTContext &Context, const Expr *Converted, - APValue &ConstantValue) const; + APValue &ConstantValue, + QualType &ConstantType) const; bool isPointerConversionToBool() const; bool isPointerConversionToVoidPointer(ASTContext& Context) const; void DebugPrint() const; diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 0b5b3b0a5e..a31b3c5bfb 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -312,7 +312,10 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ Out << ""; return; case APValue::Int: - Out << getInt(); + if (Ty->isBooleanType()) + Out << (getInt().getBoolValue() ? "true" : "false"); + else + Out << getInt(); return; case APValue::Float: Out << GetApproxValue(getFloat()); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 78a9f89d59..570b240332 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6045,7 +6045,9 @@ static void DiagnoseNarrowingInInitList(Sema &S, InitializationSequence &Seq, // C++11 [dcl.init.list]p7: Check whether this is a narrowing conversion. APValue ConstantValue; - switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue)) { + QualType ConstantType; + switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue, + ConstantType)) { case NK_Not_Narrowing: // No narrowing occurred. return; @@ -6074,7 +6076,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, InitializationSequence &Seq, diag::err_init_list_constant_narrowing_sfinae : diag::err_init_list_constant_narrowing) << PostInit->getSourceRange() - << ConstantValue.getAsString(S.getASTContext(), EntityType) + << ConstantValue.getAsString(S.getASTContext(), ConstantType) << EntityType.getLocalUnqualifiedType(); break; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index ff227eee6e..be0243403b 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -288,10 +288,13 @@ static const Expr *IgnoreNarrowingConversion(const Expr *Converted) { /// \param Converted The result of applying this standard conversion sequence. /// \param ConstantValue If this is an NK_Constant_Narrowing conversion, the /// value of the expression prior to the narrowing conversion. +/// \param ConstantType If this is an NK_Constant_Narrowing conversion, the +/// type of the expression prior to the narrowing conversion. NarrowingKind StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, const Expr *Converted, - APValue &ConstantValue) const { + APValue &ConstantValue, + QualType &ConstantType) const { assert(Ctx.getLangOpts().CPlusPlus && "narrowing check outside C++"); // C++11 [dcl.init.list]p7: @@ -325,6 +328,7 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, // If the resulting value is different, this was a narrowing conversion. if (IntConstantValue != ConvertedValue) { ConstantValue = APValue(IntConstantValue); + ConstantType = Initializer->getType(); return NK_Constant_Narrowing; } } else { @@ -354,8 +358,10 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, llvm::APFloat::rmNearestTiesToEven, &ignored); // If there was no overflow, the source value is within the range of // values that can be represented. - if (ConvertStatus & llvm::APFloat::opOverflow) + if (ConvertStatus & llvm::APFloat::opOverflow) { + ConstantType = Initializer->getType(); return NK_Constant_Narrowing; + } } else { return NK_Variable_Narrowing; } @@ -400,8 +406,10 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, ConvertedValue = ConvertedValue.extend(InitializerValue.getBitWidth()); ConvertedValue.setIsSigned(InitializerValue.isSigned()); // If the result is different, this was a narrowing conversion. - if (ConvertedValue != InitializerValue) + if (ConvertedValue != InitializerValue) { + ConstantType = Initializer->getType(); return NK_Constant_Narrowing; + } } else { // Variables are always narrowings. return NK_Variable_Narrowing; @@ -4789,8 +4797,10 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, // Check for a narrowing implicit conversion. APValue PreNarrowingValue; + QualType PreNarrowingType; bool Diagnosed = false; - switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue)) { + switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue, + PreNarrowingType)) { case NK_Variable_Narrowing: // Implicit conversion to a narrower type, and the value is not a constant // expression. We'll diagnose this in a moment. @@ -4800,7 +4810,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, case NK_Constant_Narrowing: Diag(From->getLocStart(), diag::err_cce_narrowing) << CCE << /*Constant*/1 - << PreNarrowingValue.getAsString(Context, QualType()) << T; + << PreNarrowingValue.getAsString(Context, PreNarrowingType) << T; Diagnosed = true; break; diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp index 2e0eb9c23d..4e5bc429db 100644 --- a/test/SemaCXX/constexpr-printing.cpp +++ b/test/SemaCXX/constexpr-printing.cpp @@ -96,3 +96,7 @@ void LabelDiffTest() { static_assert(mulBy3((LabelDiffTy)&&a-(LabelDiffTy)&&b) == 3, ""); // expected-error {{constant expression}} expected-note {{call to 'mulBy3(&&a - &&b)'}} a:b:return; } + +constexpr bool test_bool_printing(bool b) { return 1 / !(2*b | !(2*b)); } // expected-note 2{{division by zero}} +constexpr bool test_bool_0 = test_bool_printing(false); // expected-error {{constant expr}} expected-note {{in call to 'test_bool_printing(false)'}} +constexpr bool test_bool_1 = test_bool_printing(true); // expected-error {{constant expr}} expected-note {{in call to 'test_bool_printing(true)'}} -- 2.40.0