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

Reply via email to