]> granicus.if.org Git - clang/commitdiff
[Frontend] Correctly handle instantiating ctors with skipped bodies
authorIlya Biryukov <ibiryukov@google.com>
Thu, 28 Dec 2017 13:05:46 +0000 (13:05 +0000)
committerIlya Biryukov <ibiryukov@google.com>
Thu, 28 Dec 2017 13:05:46 +0000 (13:05 +0000)
Summary:
Previsouly clang tried instantiating member initializers even if ctor
body was skipped, this caused spurious errors (see the test).

Reviewers: sepavloff, klimek

Reviewed By: sepavloff

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D41492

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321520 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/Index/skipped-bodies-ctors.cpp [new file with mode: 0644]

index 1deb8638756bf6221c54ae4422e0ac77958aa427..d8af8f34530b17a88b1901cd11407318096a6f4a 100644 (file)
@@ -3932,22 +3932,22 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
                                          TemplateArgs))
       return;
 
-    if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
-      // If this is a constructor, instantiate the member initializers.
-      InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl),
-                                 TemplateArgs);
-
-      // If this is an MS ABI dllexport default constructor, instantiate any
-      // default arguments.
-      if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
-          Ctor->isDefaultConstructor()) {
-        InstantiateDefaultCtorDefaultArgs(*this, Ctor);
-      }
-    }
-
     if (PatternDecl->hasSkippedBody()) {
       ActOnSkippedFunctionBody(Function);
     } else {
+      if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
+        // If this is a constructor, instantiate the member initializers.
+        InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl),
+                                   TemplateArgs);
+
+        // If this is an MS ABI dllexport default constructor, instantiate any
+        // default arguments.
+        if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+            Ctor->isDefaultConstructor()) {
+          InstantiateDefaultCtorDefaultArgs(*this, Ctor);
+        }
+      }
+
       // Instantiate the function body.
       StmtResult Body = SubstStmt(Pattern, TemplateArgs);
 
diff --git a/test/Index/skipped-bodies-ctors.cpp b/test/Index/skipped-bodies-ctors.cpp
new file mode 100644 (file)
index 0000000..8a559ee
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \
+// RUN: | FileCheck --implicit-check-not "error:" %s
+
+
+template <class T>
+struct Foo {
+  template <class = int>
+  Foo(int &a) : a(a) {
+  }
+
+  int &a;
+};
+
+
+int bar = Foo<int>(bar).a + Foo<int>(bar).a;
+// CHECK-NOT: error: constructor for 'Foo<int>' must explicitly initialize the reference