[PATCH] Try to fix PR16239
Wei Pan
wei.pan at intel.com
Tue Jun 25 18:48:43 PDT 2013
wwwwpan added you to the CC list for the revision "Try to fix PR16239".
Hi rsmith, dblaikie,
- In this bug, Sema is performing a constructor initialization, and it's
associated argument conversions invoke this constructor initialization
again. This causes an infinite recursion.
http://llvm-reviews.chandlerc.com/D1038
Files:
include/clang/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaInit.cpp
test/SemaCXX/constructor.cpp
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -266,6 +266,11 @@
/// if Sema is already doing so, which would cause infinite recursions.
bool IsBuildingRecoveryCallExpr;
+ /// \brief All constructors in construction. This is to detect if
+ /// converting the arguments calls any constructor being constructed,
+ /// which leads to an infinite recursion.
+ llvm::SmallVector<CXXConstructorDecl *, 2> CtorsInConstruction;
+
/// ExprNeedsCleanups - True if the current evaluation context
/// requires cleanups to be run at its conclusion.
bool ExprNeedsCleanups;
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -10147,6 +10147,13 @@
else
ConvertedArgs.reserve(NumArgs);
+ // Mark this constructor being constructed so that its argument construction
+ // should not call itself.
+ CXXConstructorDecl *Ctor = Constructor;
+ if (FunctionTemplateDecl *FuncTmpl = Ctor->getPrimaryTemplate())
+ Ctor = cast<CXXConstructorDecl>(FuncTmpl->getTemplatedDecl());
+ CtorsInConstruction.push_back(Ctor);
+
VariadicCallType CallType =
Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply;
SmallVector<Expr *, 8> AllArgs;
@@ -10165,6 +10172,9 @@
AllArgs.size()),
Proto, Loc);
+ // Cleanup once finished the constructor call.
+ CtorsInConstruction.pop_back();
+
return Invalid;
}
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -3008,7 +3008,15 @@
SuppressUserConversions = true;
}
- if (!Constructor->isInvalidDecl() &&
+ // If Sema is already building this constructor call, then this constructor
+ // cannot be a candidate for initializing its arguments. Otherwise, this
+ // leads to an infinite recursion.
+ bool InConstruction =
+ S.CtorsInConstruction.end() != std::find(S.CtorsInConstruction.begin(),
+ S.CtorsInConstruction.end(),
+ Constructor);
+
+ if (!Constructor->isInvalidDecl() && !InConstruction &&
(AllowExplicit || !Constructor->isExplicit()) &&
(!OnlyListConstructors || S.isInitListConstructor(Constructor))) {
if (ConstructorTmpl)
Index: test/SemaCXX/constructor.cpp
===================================================================
--- test/SemaCXX/constructor.cpp
+++ test/SemaCXX/constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
typedef int INT;
class Foo {
@@ -85,3 +85,34 @@
A::S::~S() {}
+namespace PR16239 {
+struct Foo;
+struct Bar;
+
+struct Move2 {
+ Move2(Foo f); // expected-note {{passing argument to parameter 'f' here}}
+ Move2(Bar b); // expected-note {{passing argument to parameter 'b' here}}
+};
+
+struct Foo {
+ Foo(const Move2&);
+
+ Foo(Foo&); // expected-note {{candidate constructor not viable}}
+};
+
+struct Bar {
+ template <typename T = int>
+ Bar(const Move2&, T t = T());
+
+ Bar(Bar&); // expected-note {{candidate constructor not viable}}
+};
+
+Foo func_foo();
+Bar func_bar();
+
+void Baz() {
+ Foo f = func_foo(); // expected-error{{no matching constructor for initialization}}
+ Bar b = func_bar(); // expected-error{{no matching constructor for initialization}}
+}
+
+} // namespace
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1038.1.patch
Type: text/x-patch
Size: 3675 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130625/ce0a4f69/attachment.bin>
More information about the cfe-commits
mailing list