courbet created this revision. courbet added reviewers: aaron.ballman, Quuxplusone. Herald added a subscriber: cfe-commits.
Handles expressions such as: - `std::is_const<T>()` - `std::is_const<T>()()`; - `std::is_same(decltype(U()), V>::value`; Repository: rC Clang https://reviews.llvm.org/D55552 Files: lib/Sema/SemaTemplate.cpp test/SemaCXX/static-assert.cpp
Index: test/SemaCXX/static-assert.cpp =================================================================== --- test/SemaCXX/static-assert.cpp +++ test/SemaCXX/static-assert.cpp @@ -76,6 +76,8 @@ static const Tp value = v; typedef Tp value_type; typedef integral_constant type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } }; template <class Tp, Tp v> @@ -103,6 +105,7 @@ } // namespace std struct ExampleTypes { + explicit ExampleTypes(int); using T = int; using U = float; }; @@ -119,6 +122,18 @@ // expected-error@-1{{static_assert failed due to requirement 'std::is_const<const int>::value == false' "message"}} static_assert(!(std::is_const<const ExampleTypes::T>::value == true), "message"); // expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>::value == true)' "message"}} +static_assert(std::is_const<ExampleTypes::T>(), "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>()' "message"}} +static_assert(!(std::is_const<const ExampleTypes::T>()()), "message"); +// expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>()())' "message"}} +static_assert(std::is_same<decltype(std::is_const<const ExampleTypes::T>()), int>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_same<std::is_const<const int>, int>::value' "message"}} +static_assert(std::is_const<decltype(ExampleTypes::T(3))>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}} +static_assert(std::is_const<decltype(ExampleTypes::T())>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}} +static_assert(std::is_const<decltype(ExampleTypes(3))>::value, "message"); +// expected-error@-1{{static_assert failed due to requirement 'std::is_const<ExampleTypes>::value' "message"}} struct BI_tag {}; struct RAI_tag : BI_tag {}; Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -3059,8 +3059,9 @@ // for actual types. class FailedBooleanConditionPrinterHelper : public PrinterHelper { public: - explicit FailedBooleanConditionPrinterHelper(const PrintingPolicy &P) - : Policy(P) {} + FailedBooleanConditionPrinterHelper(const ASTContext &Context, + const PrintingPolicy &P) + : Context(Context), Policy(P) {} bool handledStmt(Stmt *E, raw_ostream &OS) override { const auto *DR = dyn_cast<DeclRefExpr>(E); @@ -3077,10 +3078,38 @@ } return true; } + if (auto *Node = dyn_cast<CXXTemporaryObjectExpr>(E)) { + Node->getType().getCanonicalType().print(OS, Policy); + if (Node->isStdInitListInitialization()) + /* Nothing to do; braces are part of creating the std::initializer_list. + */ + ; + else if (Node->isListInitialization()) + OS << "{"; + else + OS << "("; + for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), + ArgEnd = Node->arg_end(); + Arg != ArgEnd; ++Arg) { + if ((*Arg)->isDefaultArgument()) + break; + if (Arg != Node->arg_begin()) + OS << ", "; + (*Arg)->printPretty(OS, this, Policy); + } + if (Node->isStdInitListInitialization()) + /* See above. */; + else if (Node->isListInitialization()) + OS << "}"; + else + OS << ")"; + return true; + } return false; } private: + const ASTContext &Context; const PrintingPolicy Policy; }; @@ -3122,7 +3151,7 @@ std::string Description; { llvm::raw_string_ostream Out(Description); - FailedBooleanConditionPrinterHelper Helper(getPrintingPolicy()); + FailedBooleanConditionPrinterHelper Helper(Context, getPrintingPolicy()); FailedCond->printPretty(Out, &Helper, getPrintingPolicy()); } return { FailedCond, Description };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits