On 13/01/15 23:16, Richard Smith wrote:
On Thu, Nov 27, 2014 at 2:50 PM, Vassil Vassilev <[email protected]
<mailto:[email protected]>> wrote:
On 25/11/14 00:52, Richard Smith wrote:
+ } + else if
(!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
Per the LLVM coding style, put the close brace and the 'else' on
the same line.
+ isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) { +
// Happens in cases where module A contains only a fwd decl and
module B + // contains the definition.
There are other conditions here; I don't think this comment is
particularly helpful. Just remove it?
+ FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); +
while (PrevFD) { + Reader.Context.adjustExceptionSpec(PrevFD,
EPI.ExceptionSpec); + PrevFD = PrevFD->getPreviousDecl();
Please use a separate variable for this loop rather than reusing
PrevFD. It's only by coincidence that this code is at the end of
the function; it shouldn't be changing function-scope state like
this.
All good points, thanks!
It seems like it should be possible to produce a testcase for
this. You'd need something like:
A.h:
struct A { A(); } b{}, c(b); // computed exception spec for copy
ctor and move ctor
B.h:
struct A { A(); } a{}; // EST_Unevaluated for copy ctor and move
ctor
... then import A and B, and do something that assumes that every
declaration has an exception specification if any declaration does.
Thanks for the pointer. I managed to reproduce the behavior, i.e
unevaluated exception spec as a first/canonical redecl (see the
new attached patch). However this test doesn't trigger the
original issue (and thus not testing anything :( )
http://llvm.org/bugs/show_bug.cgi?id=21687
There the setup is more difficult, because I need to generate a
unevaluated exception spec dtor as a first redecl and go through
clang::FunctionProtoType::isNothrow to get the assertion. To make
things worse, this base dtor must be emitted as an alias. Could
you help me out?
Ugh, getting good modules testcases is hard. I'm not sure I follow
what you said above, though: does the testcase in your patch fail
without the code change and pass with it? If so, I think that's
enough. (Or does it only fail with a previous revision of the patch
and pass with both trunk and the patched code?)
Sorry for the delay. The attached test contains all preconditions caused
the crash in bugid=21687. The problem is that I am missing a statement,
which forces clang to call clang::FunctionProtoType::isNothrow and die
with an assert. One way to do it is via:
clang::CodeGen::CodeGenModule::EmitGlobalDefinition ->
clang::CodeGen::CodeGenModule::codegenCXXStructor->
clang::CodeGen::CodeGenModule::getAddrOfCXXStructor ->
clang::CodeGen::CodeGenModule::GetOrCreateLLVMFunction ->
clang::CodeGen::CodeGenModule::SetFunctionAttributes ->
clang::CodeGen::CodeGenModule::SetLLVMFunctionAttributes ->
clang::CodeGen::CodeGenModule::ConstructAttributeList call chain.
However I don't know how to make this happen for the dtors in the test.
I'd be happy to discuss that in IRC if you need more feedback.
+ FunctionDecl* PrevFDToUpdate = PrevFD; + while (PrevFDToUpdate) { +
Reader.Context.adjustExceptionSpec(PrevFDToUpdate, EPI.ExceptionSpec);
+ PrevFDToUpdate = PrevFDToUpdate->getPreviousDecl();
The "*" should go on the right, and this would (to me) read better as
a for loop:
for (FunctionDecl *PrevFDToUpdate = PrevFD; PrevFDToUpdate;
PrevFDToUpdate = PrevFDToUpdate->getPreviousDecl())
Reader.Context.adjustExceptionSpec(PrevFDToUpdate, EPI.ExceptionSpec);
I agree it looks much nicer.
Vassil
Other than that, LGTM.
Vassil
On Mon, Nov 24, 2014 at 11:09 AM, Vassil Vassilev
<[email protected] <mailto:[email protected]>> wrote:
Sorry for the delay. Attaching the new version.
Vassil
On 14/11/14 02:47, Richard Smith wrote:
+ }
+ else { // FPT->getExceptionSpecType() is resolved and
the other is not
You're not checking for this condition; the code here is
getting run even if both or neither are unresolved.
The patch needs rebasing (we have a new helper function in
ASTContext to update the exception specification of a
declaration), but looks like the right direction.
On Thu, Nov 6, 2014 at 4:23 AM, Vassil Vassilev
<[email protected]
<mailto:[email protected]>> wrote:
Hi Richard,
I am attaching the patch we discussed at the dev
meeting. Still haven't found small reproducer...
The issue appears to stem from the fact that module A
contains only a forward declaration of a function and it
exception spec cannot be computed. In module B is the
definition with computed exception spec, which gets
deserialized after the one in module A. This patch
teaches the ASTDeclReader to update all the exception
specs of the previous decls to the current one.
Could you review, please?
Many thanks,
Vassil
_______________________________________________
cfe-commits mailing list
[email protected] <mailto:[email protected]>
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
From ec324286a30dc142de21c1c3a0b5d5c3cb6d7e95 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <[email protected]>
Date: Mon, 24 Nov 2014 19:58:23 +0100
Subject: [PATCH] [modules] Update exception specs of the redecl chain when
deserializing a module.
The issue appears to stem from the fact that module A contains only a forward
declaration of a function and it exception spec cannot be computed. In module B
is the definition with computed exception spec, which gets deserialized after
the one in module A. This patch teaches the ASTDeclReader to update all the
exception specs of the previous decls to the current one.
Test case shows the issue but doesn't reproduce the crash of
http://llvm.org/bugs/show_bug.cgi?id=21687
---
lib/Serialization/ASTReaderDecl.cpp | 15 +++++++++++----
test/Modules/Inputs/PR21687/A.h | 4 ++++
test/Modules/Inputs/PR21687/B.h | 4 ++++
test/Modules/Inputs/PR21687/module.modulemap | 10 ++++++++++
test/Modules/pr21687.cpp | 10 ++++++++++
5 files changed, 39 insertions(+), 4 deletions(-)
create mode 100644 test/Modules/Inputs/PR21687/A.h
create mode 100644 test/Modules/Inputs/PR21687/B.h
create mode 100644 test/Modules/Inputs/PR21687/module.modulemap
create mode 100644 test/Modules/pr21687.cpp
diff --git a/lib/Serialization/ASTReaderDecl.cpp
b/lib/Serialization/ASTReaderDecl.cpp
index 5aeb3d1..eae4116 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -2831,11 +2831,18 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader
&Reader,
// specification now.
auto *FPT = FD->getType()->getAs<FunctionProtoType>();
auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>();
- if (FPT && PrevFPT &&
- isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
- !isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) {
- Reader.Context.adjustExceptionSpec(
+ if (FPT && PrevFPT) {
+ if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
+ !isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) {
+ Reader.Context.adjustExceptionSpec(
FD, PrevFPT->getExtProtoInfo().ExceptionSpec);
+ } else if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
+ isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) {
+ FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+ for (FunctionDecl *PrevFDToUpdate = PrevFD; PrevFDToUpdate;
+ PrevFDToUpdate = PrevFDToUpdate->getPreviousDecl())
+ Reader.Context.adjustExceptionSpec(PrevFDToUpdate, EPI.ExceptionSpec);
+ }
}
}
}
diff --git a/test/Modules/Inputs/PR21687/A.h b/test/Modules/Inputs/PR21687/A.h
new file mode 100644
index 0000000..86f2d1e
--- /dev/null
+++ b/test/Modules/Inputs/PR21687/A.h
@@ -0,0 +1,4 @@
+struct A {
+ A(){}
+ virtual ~A() {}
+} b{}, c(b); // computed exception spec for copy ctor and move ctor
diff --git a/test/Modules/Inputs/PR21687/B.h b/test/Modules/Inputs/PR21687/B.h
new file mode 100644
index 0000000..bded111
--- /dev/null
+++ b/test/Modules/Inputs/PR21687/B.h
@@ -0,0 +1,4 @@
+struct A {
+ A(){}
+ virtual ~A() {}
+} a{}; // EST_Unevaluated for copy ctor and move ctor
diff --git a/test/Modules/Inputs/PR21687/module.modulemap
b/test/Modules/Inputs/PR21687/module.modulemap
new file mode 100644
index 0000000..5bce4f7
--- /dev/null
+++ b/test/Modules/Inputs/PR21687/module.modulemap
@@ -0,0 +1,10 @@
+module modA {
+ header "A.h"
+ export *
+}
+
+module modB {
+ header "B.h"
+ export *
+}
+
diff --git a/test/Modules/pr21687.cpp b/test/Modules/pr21687.cpp
new file mode 100644
index 0000000..a4fe69c
--- /dev/null
+++ b/test/Modules/pr21687.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -std=c++11 %s
+
+#include "Inputs/PR21687/B.h"
+A tmp;
+#include "Inputs/PR21687/A.h"
+
+int main() {
+ A tmp1;
+}
--
1.9.3 (Apple Git-50)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits