Mordante created this revision.
Mordante added reviewers: sepavloff, rsmith.
Mordante added a project: clang.

This fixes https://bugs.llvm.org/show_bug.cgi?id=28500


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D65694

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/SemaTemplate/default-arguments-cxx0x.cpp

Index: clang/test/SemaTemplate/default-arguments-cxx0x.cpp
===================================================================
--- clang/test/SemaTemplate/default-arguments-cxx0x.cpp
+++ clang/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -114,3 +114,34 @@
     S<int> _a{};
   };
 }
+
+// https://bugs.llvm.org/show_bug.cgi?id=28500
+// Failure to resolve the decltype part during instantiation caused an
+// assertion failure
+namespace PR28500 {
+namespace original {
+template <class T>
+void bar(T t = [](decltype(t) i) { return 0; }(0)) {}
+void foo() {
+  bar<int>();
+}
+} // namespace original
+
+namespace cast {
+template <class T>
+void bar(T t = decltype(t)(0)) {}
+void foo() {
+  bar<int>();
+  bar<double>();
+}
+} // namespace cast
+
+namespace value {
+template <class T>
+void bar(T t = decltype(t)()) {}
+void foo() {
+  bar<int>();
+  bar<double>();
+}
+} // namespace value
+} // namespace PR28500
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5287,29 +5287,33 @@
     //   }
     //
     // In this case instantiation of the type of 'g1' requires definition of
-    // 'x1', which is defined later. Error recovery may produce an enum used
-    // before definition. In these cases we need to instantiate relevant
-    // declarations here.
+    // 'x1', which is defined later.
+    //
+    // Error recovery may produce an enum used before definition.
+    //
+    // Default arguments with a decltype referencing arguments:
+    //
+    //   template <class T> void bar(T t = decltype(t)()) {}
+    //
+    // Else we must have a label decl that hasn't been found yet.
+    //
+    // In these cases we need to instantiate relevant declarations here.
     bool NeedInstantiate = false;
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
       NeedInstantiate = RD->isLocalClass();
     else
-      NeedInstantiate = isa<EnumDecl>(D);
+      NeedInstantiate =
+          isa<EnumDecl>(D) || isa<LabelDecl>(D) || isa<ParmVarDecl>(D);
     if (NeedInstantiate) {
       Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
+      assert(Inst && "Failed to instantiate");
       CurrentInstantiationScope->InstantiatedLocal(D, Inst);
-      return cast<TypeDecl>(Inst);
+      return cast<NamedDecl>(Inst);
     }
 
-    // If we didn't find the decl, then we must have a label decl that hasn't
-    // been found yet.  Lazily instantiate it and return it now.
-    assert(isa<LabelDecl>(D));
-
-    Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
-    assert(Inst && "Failed to instantiate label??");
+    assert(0 && "Failed to instantiate");
 
-    CurrentInstantiationScope->InstantiatedLocal(D, Inst);
-    return cast<LabelDecl>(Inst);
+    return nullptr;
   }
 
   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2974,6 +2974,11 @@
   if (isa<EnumDecl>(D))
     return nullptr;
 
+  // Default arguments with a decltype referencing arguments prior to definition
+  // may require instantiation.
+  if (isa<ParmVarDecl>(D))
+    return nullptr;
+
   // If we didn't find the decl, then we either have a sema bug, or we have a
   // forward reference to a label declaration.  Return null to indicate that
   // we have an uninstantiated label.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to