[PATCH] D27116: Fix crash when using __has_nothrow_copy with inherited constructors
Philippe Daouadi via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 25 12:56:17 PST 2016
blastrock updated this revision to Diff 79319.
blastrock added a comment.
I got what "shadows" means, this patch can handle a UsingDecl with multiple shadows.
https://reviews.llvm.org/D27116
Files:
lib/Sema/SemaExprCXX.cpp
test/CXX/special/class.copy/p34-cxx11.cpp
Index: test/CXX/special/class.copy/p34-cxx11.cpp
===================================================================
--- /dev/null
+++ test/CXX/special/class.copy/p34-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// expected-no-diagnostics
+
+struct A {
+ A(A const &) noexcept(false) {}
+ A(A&&) noexcept(true) {}
+};
+
+struct B : public A {
+ using A::A;
+};
+
+static_assert(!__has_nothrow_copy(B), "has_nothrow_copy fails");
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -4418,19 +4418,34 @@
// resolution point.
if (isa<FunctionTemplateDecl>(ND))
continue;
- const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
- if (Constructor->isCopyConstructor(FoundTQs)) {
- FoundConstructor = true;
- const FunctionProtoType *CPT
- = Constructor->getType()->getAs<FunctionProtoType>();
- CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
- if (!CPT)
- return false;
- // TODO: check whether evaluating default arguments can throw.
- // For now, we'll be conservative and assume that they can throw.
- if (!CPT->isNothrow(C) || CPT->getNumParams() > 1)
- return false;
- }
+
+ auto const HandleConstructor =
+ [&](const CXXConstructorDecl *Constructor) {
+ if (Constructor->isCopyConstructor(FoundTQs)) {
+ FoundConstructor = true;
+ const FunctionProtoType *CPT =
+ Constructor->getType()->getAs<FunctionProtoType>();
+ CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
+ if (!CPT)
+ return false;
+ // TODO: check whether evaluating default arguments can throw.
+ // For now, we'll be conservative and assume that they can
+ // throw.
+ if (!CPT->isNothrow(C) || CPT->getNumParams() > 1)
+ return false;
+ }
+ return true;
+ };
+
+ // handle inherited constructors
+ if (isa<UsingDecl>(ND)) {
+ const auto *UD = cast<UsingDecl>(ND);
+ for (const auto &C : UD->shadows())
+ if (!HandleConstructor(
+ cast<CXXConstructorDecl>(C->getTargetDecl())))
+ return false;
+ } else if (!HandleConstructor(cast<CXXConstructorDecl>(ND)))
+ return false;
}
return FoundConstructor;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27116.79319.patch
Type: text/x-patch
Size: 2626 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161125/ae7a30c3/attachment.bin>
More information about the llvm-commits
mailing list