jdemeule created this revision. jdemeule added a reviewer: rsmith. jdemeule added a project: clang.
Clang will report an error when the exception specification is not respected with a fix-it. However, this fix-it does not fully qualify the type in case of function template specialization which lead to "incomplete" transformation (resulting code does not compile). This patch attempts to create a more realiable in the first place by reusing the pretty printer helper defined in `SemaTemplate` which expand template arguments. Repository: rC Clang https://reviews.llvm.org/D69475 Files: clang/include/clang/AST/PrettyPrinter.h clang/lib/AST/StmtPrinter.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/SemaCXX/exception-spec.cpp
Index: clang/test/SemaCXX/exception-spec.cpp =================================================================== --- clang/test/SemaCXX/exception-spec.cpp +++ clang/test/SemaCXX/exception-spec.cpp @@ -52,3 +52,21 @@ D2 &operator=(const D2&); // expected-error {{more lax}} }; } + +namespace MissingOnTemplate { + template<class T> + struct type_dependant_noexcept { + static constexpr const bool value = (sizeof(T) < 4); + }; + + template<typename T> void a_fct(T) noexcept(type_dependant_noexcept<T>::value); // expected-note {{previous}} + template<typename T> void a_fct(T); // expected-error {{missing exception specification 'noexcept(type_dependant_noexcept<T>::value)'}} +} + +namespace abc { + struct A {}; +} // namespace abc + +namespace MissingOnTemplate { + template<>void a_fct<abc::A>(abc::A); // expected-error {{missing exception specification 'noexcept(type_dependant_noexcept<abc::A>::value)'}} expected-note {{previous}} +} \ No newline at end of file Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -3115,40 +3115,6 @@ return Cond; } -namespace { - -// A PrinterHelper that prints more helpful diagnostics for some sub-expressions -// within failing boolean expression, such as substituting template parameters -// for actual types. -class FailedBooleanConditionPrinterHelper : public PrinterHelper { -public: - explicit FailedBooleanConditionPrinterHelper(const PrintingPolicy &P) - : Policy(P) {} - - bool handledStmt(Stmt *E, raw_ostream &OS) override { - const auto *DR = dyn_cast<DeclRefExpr>(E); - if (DR && DR->getQualifier()) { - // If this is a qualified name, expand the template arguments in nested - // qualifiers. - DR->getQualifier()->print(OS, Policy, true); - // Then print the decl itself. - const ValueDecl *VD = DR->getDecl(); - OS << VD->getName(); - if (const auto *IV = dyn_cast<VarTemplateSpecializationDecl>(VD)) { - // This is a template variable, print the expanded template arguments. - printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy); - } - return true; - } - return false; - } - -private: - const PrintingPolicy Policy; -}; - -} // end anonymous namespace - std::pair<Expr *, std::string> Sema::findFailedBooleanCondition(Expr *Cond) { Cond = lookThroughRangesV3Condition(PP, Cond); @@ -3187,7 +3153,7 @@ llvm::raw_string_ostream Out(Description); PrintingPolicy Policy = getPrintingPolicy(); Policy.PrintCanonicalTypes = true; - FailedBooleanConditionPrinterHelper Helper(Policy); + ExpandTemplateArgumentsPrinterHelper Helper(Policy); FailedCond->printPretty(Out, &Helper, Policy, 0, "\n", nullptr); } return { FailedCond, Description }; Index: clang/lib/Sema/SemaExceptionSpec.cpp =================================================================== --- clang/lib/Sema/SemaExceptionSpec.cpp +++ clang/lib/Sema/SemaExceptionSpec.cpp @@ -423,7 +423,11 @@ case EST_NoexceptTrue: OS << "noexcept("; assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr"); - OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy()); + { + PrintingPolicy Policy = getPrintingPolicy(); + ExpandTemplateArgumentsPrinterHelper Helper(Policy); + OldProto->getNoexceptExpr()->printPretty(OS, &Helper, Policy); + } OS << ")"; break; case EST_NoThrow: Index: clang/lib/AST/StmtPrinter.cpp =================================================================== --- clang/lib/AST/StmtPrinter.cpp +++ clang/lib/AST/StmtPrinter.cpp @@ -2472,3 +2472,26 @@ // Implement virtual destructor. PrinterHelper::~PrinterHelper() = default; + +//===----------------------------------------------------------------------===// +// ExpandTemplateArgumentsPrinterHelper +//===----------------------------------------------------------------------===// + +bool ExpandTemplateArgumentsPrinterHelper::handledStmt(Stmt *E, + raw_ostream &OS) { + const auto *DR = dyn_cast<DeclRefExpr>(E); + if (DR && DR->getQualifier()) { + // If this is a qualified name, expand the template arguments in nested + // qualifiers. + DR->getQualifier()->print(OS, Policy, true); + // Then print the decl itself. + const ValueDecl *VD = DR->getDecl(); + OS << VD->getName(); + if (const auto *IV = dyn_cast<VarTemplateSpecializationDecl>(VD)) { + // This is a template variable, print the expanded template arguments. + printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy); + } + return true; + } + return false; +} \ No newline at end of file Index: clang/include/clang/AST/PrettyPrinter.h =================================================================== --- clang/include/clang/AST/PrettyPrinter.h +++ clang/include/clang/AST/PrettyPrinter.h @@ -234,6 +234,20 @@ std::function<std::string(StringRef)> remapPath; }; +/// A PrinterHelper that prints more helpful diagnostics for some +/// sub-expressions within failing boolean expression, such as substituting +/// template parameters for actual types. +class ExpandTemplateArgumentsPrinterHelper : public PrinterHelper { +public: + explicit ExpandTemplateArgumentsPrinterHelper(const PrintingPolicy &P) + : Policy(P) {} + + bool handledStmt(Stmt *E, raw_ostream &OS) override; + +private: + const PrintingPolicy Policy; +}; + } // end namespace clang #endif
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits