diff options
author | Richard Trieu <rtrieu@google.com> | 2019-05-04 04:22:33 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2019-05-04 04:22:33 +0000 |
commit | c09c3b4c90d5a5730fd018ca56385437d667b1bf (patch) | |
tree | bf4199953383e24e2af26fa67e2b79d912b68f6e /test/Modules/odr_hash.cpp | |
parent | e9b780230d2dde954d8f6750e05c4b89bc99f0d7 (diff) |
Reduce amount of work ODR hashing does.
When a FunctionProtoType is in the original type in a DecayedType, the decayed
type is a PointerType which points back the original FunctionProtoType. The
visitor for ODRHashing will attempt to process both Type's, doing double work.
By chaining together multiple DecayedType's and FunctionProtoType's, this would
result in 2^N Type's visited only N DecayedType's and N FunctionProtoType's
exsit. Another bug where VisitDecayedType and VisitAdjustedType did
redundant work doubled the work at each level, giving 4^N Type's visited. This
patch removed the double work and detects when a FunctionProtoType decays to
itself to only check the Type once. This lowers the exponential runtime to
linear runtime. Fixes https://bugs.llvm.org/show_bug.cgi?id=41625
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359960 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Modules/odr_hash.cpp')
-rw-r--r-- | test/Modules/odr_hash.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index e4c5ba6f82..f22a8b8f8a 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -4587,6 +4587,43 @@ int num = bar(); #endif } +namespace FunctionProtoTypeDecay { +#if defined(FIRST) +struct S1 { + struct X {}; + using Y = X(X()); +}; +#elif defined(SECOND) +struct S1 { + struct X {}; + using Y = X(X(X())); +}; +#else +S1 s1; +// expected-error@first.h:* {{'FunctionProtoTypeDecay::S1::Y' from module 'FirstModule' is not present in definition of 'FunctionProtoTypeDecay::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'Y' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + struct X {}; + using Y = + X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X( + X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X( + X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X( + X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X( + )))))))))))))))) + )))))))))))))))) + )))))))))))))))) + )))))))))))))))); +}; +#elif defined(SECOND) +#else +S2 s2; +#endif + +} + // Keep macros contained to one file. #ifdef FIRST #undef FIRST |