r317394 - Update ODR hashing tests
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 3 18:20:50 PDT 2017
Author: rtrieu
Date: Fri Nov 3 18:20:50 2017
New Revision: 317394
URL: http://llvm.org/viewvc/llvm-project?rev=317394&view=rev
Log:
Update ODR hashing tests
Add a mix of postive and negative tests to check that wrong Decls won't be
flagged in the diagnostic. Split the check everything test and moved the
pieces closer to where the related tests are.
Modified:
cfe/trunk/test/Modules/odr_hash.cpp
Modified: cfe/trunk/test/Modules/odr_hash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=317394&r1=317393&r2=317394&view=diff
==============================================================================
--- cfe/trunk/test/Modules/odr_hash.cpp (original)
+++ cfe/trunk/test/Modules/odr_hash.cpp Fri Nov 3 18:20:50 2017
@@ -12,6 +12,10 @@
// RUN: echo "#define SECOND" >> %t/Inputs/second.h
// RUN: cat %s >> %t/Inputs/second.h
+// Test that each header can compile
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/first.h
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/second.h
+
// Build module map file
// RUN: echo "module FirstModule {" >> %t/Inputs/module.map
// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map
@@ -28,6 +32,13 @@
#include "second.h"
#endif
+// Used for testing
+#if defined(FIRST)
+#define ACCESS public:
+#elif defined(SECOND)
+#define ACCESS private:
+#endif
+
namespace AccessSpecifiers {
#if defined(FIRST)
struct S1 {
@@ -55,6 +66,32 @@ S2 s2;
// expected-error at second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}
// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
+
+#define DECLS \
+public: \
+private: \
+protected:
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'AccessSpecifiers::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+
+#undef DECLS
} // namespace AccessSpecifiers
namespace StaticAssert {
@@ -113,7 +150,31 @@ S4 s4;
// expected-error at second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
// expected-note at first.h:* {{but in 'FirstModule' found static assert}}
#endif
-}
+
+#define DECLS \
+ static_assert(4 == 4, "Message"); \
+ static_assert(5 == 5);
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'StaticAssert::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace StaticAssert
namespace Field {
#if defined(FIRST)
@@ -302,6 +363,38 @@ S13 s13;
// expected-error at first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
+
+#define DECLS \
+ int a; \
+ int b : 3; \
+ unsigned c : 1 + 2; \
+ s d; \
+ double e = 1.0; \
+ long f[5];
+
+#if defined(FIRST) || defined(SECOND)
+typedef short s;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'Field::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Field
namespace Method {
@@ -531,6 +624,40 @@ S15 s15;
// expected-error at first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'A' does not match}}
#endif
+
+#define DECLS \
+ void A(); \
+ static void B(); \
+ virtual void C(); \
+ virtual void D() = 0; \
+ inline void E(); \
+ void F() const; \
+ void G() volatile; \
+ void H(int x); \
+ void I(int x = 5 + 5); \
+ void J(int); \
+ void K(int x[2]); \
+ int L();
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1* v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1* i1;
+// expected-error at second.h:* {{'Method::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Method
namespace Constructor {
@@ -565,6 +692,31 @@ S2* s2;
// expected-error at second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}}
// expected-note at first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}}
#endif
+
+#define DECLS(CLASS) \
+ CLASS(int); \
+ CLASS(double); \
+ CLASS(int, int);
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS(Valid1)
+};
+#else
+Valid1* v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS(Invalid1)
+ ACCESS
+};
+#else
+Invalid1* i1;
+// expected-error at second.h:* {{'Constructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Constructor
namespace Destructor {
@@ -600,32 +752,44 @@ S2 s2;
// expected-note at first.h:* {{but in 'FirstModule' found destructor is virtual}}
#endif
-} // namespace Destructor
-
-// Naive parsing of AST can lead to cycles in processing. Ensure
-// self-references don't trigger an endless cycles of AST node processing.
-namespace SelfReference {
-#if defined(FIRST)
-template <template <int> class T> class Wrapper {};
-
-template <int N> class S {
- S(Wrapper<::SelfReference::S> &Ref) {}
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ ~Valid1();
};
+#else
+Valid1 v1;
+#endif
-struct Xx {
- struct Yy {
- };
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ ~Invalid1();
+ ACCESS
};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'Destructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
-Xx::Xx::Xx::Yy yy;
+#if defined(FIRST) || defined(SECOND)
+struct Valid2 {
+ virtual ~Valid2();
+};
+#else
+Valid2 v2;
+#endif
-namespace NNS {
-template <typename> struct Foo;
-template <template <class> class T = NNS::Foo>
-struct NestedNamespaceSpecifier {};
-}
+#if defined(FIRST) || defined(SECOND)
+struct Invalid2 {
+ virtual ~Invalid2();
+ ACCESS
+};
+#else
+Invalid2 i2;
+// expected-error at second.h:* {{'Destructor::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
-} // namespace SelfReference
+} // namespace Destructor
namespace TypeDef {
#if defined(FIRST)
@@ -722,6 +886,35 @@ S6 s6;
// expected-error at second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}
// expected-note at first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
#endif
+
+#define DECLS \
+ typedef int A; \
+ typedef double B; \
+ typedef I C;
+
+#if defined(FIRST) || defined(SECOND)
+typedef int I;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'TypeDef::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace TypeDef
namespace Using {
@@ -819,6 +1012,35 @@ S6 s6;
// expected-error at second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}
// expected-note at first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
#endif
+
+#if defined(FIRST) || defined(SECOND)
+using I = int;
+#endif
+
+#define DECLS \
+ using A = int; \
+ using B = double; \
+ using C = I;
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'Using::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Using
namespace RecordType {
@@ -837,7 +1059,34 @@ S1 s1;
// expected-error at first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
-}
+
+#define DECLS \
+ Foo F;
+
+#if defined(FIRST) || defined(SECOND)
+struct Foo {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'RecordType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace RecordType
namespace DependentType {
#if defined(FIRST)
@@ -856,7 +1105,34 @@ using U1 = S1<T>;
// expected-error at first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
-}
+
+#define DECLS \
+ typename T::typeA x;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T>
+struct Valid1 {
+ DECLS
+};
+#else
+template <class T>
+using V1 = Valid1<T>;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T>
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+template <class T>
+using I1 = Invalid1<T>;
+// expected-error at second.h:* {{'DependentType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace DependentType
namespace ElaboratedType {
#if defined(FIRST)
@@ -874,7 +1150,34 @@ S1 s1;
// expected-error at first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
-}
+
+#define DECLS \
+ NS::type x;
+
+#if defined(FIRST) || defined(SECOND)
+namespace NS { using type = float; }
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'ElaboratedType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace ElaboratedType
namespace Enum {
#if defined(FIRST)
@@ -892,6 +1195,33 @@ S1 s1;
// expected-error at first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
+
+#define DECLS \
+ E e = E1;
+
+#if defined(FIRST) || defined(SECOND)
+enum E { E1, E2 };
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'Enum::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
}
namespace NestedNamespaceSpecifier {
@@ -1069,7 +1399,73 @@ S10 s10;
// expected-note at first.h:* {{declaration of 'x' does not match}}
#endif
}
+
+#define DECLS \
+ NS1::Type a; \
+ NS1::NS2::Type b; \
+ NS1::S c; \
+ NS3::Type d;
+
+#if defined(FIRST) || defined(SECOND)
+namespace NS1 {
+ using Type = int;
+ namespace NS2 {
+ using Type = double;
+ }
+ struct S {};
}
+namespace NS3 = NS1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'NestedNamespaceSpecifier::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+
+#define DECLS \
+ typename T::type *x = {}; \
+ int y = x->T::foo(); \
+ int z = U::template X<int>::value;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Valid2 {
+ DECLS
+};
+#else
+template <class T, class U>
+using V2 = Valid2<T, U>;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Invalid2 {
+ DECLS
+ ACCESS
+};
+#else
+template <class T, class U>
+using I2 = Invalid2<T, U>;
+// expected-error at second.h:* {{'NestedNamespaceSpecifier::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace NestedNamespaceSpecifier
namespace TemplateSpecializationType {
#if defined(FIRST)
@@ -1103,7 +1499,40 @@ S2 s2;
// expected-error at first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'u' does not match}}
#endif
-}
+
+#define DECLS \
+ OneTemplateArg<int> x; \
+ OneTemplateArg<double> y; \
+ OneTemplateArg<char *> z; \
+ TwoTemplateArgs<int, int> a; \
+ TwoTemplateArgs<double, float> b; \
+ TwoTemplateArgs<short *, char> c;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T> struct OneTemplateArg {};
+template <class T, class U> struct TwoTemplateArgs {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+DECLS
+ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'TemplateSpecializationType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateSpecializationType
namespace TemplateArgument {
#if defined(FIRST)
@@ -1205,7 +1634,43 @@ S6 s6;
// expected-error at second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
// expected-note at first.h:* {{but in 'FirstModule' found field 'x'}}
#endif
-}
+
+#define DECLS \
+ OneClass<int> a; \
+ OneInt<1> b; \
+ using c = OneClass<float>; \
+ using d = OneInt<2>; \
+ using e = OneInt<2 + 2>; \
+ OneTemplateClass<OneClass> f; \
+ OneTemplateInt<OneInt> g;
+
+#if defined(FIRST) || defined(SECOND)
+template <class> struct OneClass{};
+template <int> struct OneInt{};
+template <template <class> class> struct OneTemplateClass{};
+template <template <int> class> struct OneTemplateInt{};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+DECLS
+ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'TemplateArgument::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateArgument
namespace TemplateTypeParmType {
#if defined(FIRST)
@@ -1247,7 +1712,41 @@ using TemplateTypeParmType::S2;
// expected-error at first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'type' does not match}}
#endif
-}
+
+#define DECLS \
+ T t; \
+ U u; \
+ ParameterPack<T> a; \
+ ParameterPack<T, U> b; \
+ ParameterPack<U> c; \
+ ParameterPack<U, T> d;
+
+#if defined(FIRST) || defined(SECOND)
+template <class ...Ts> struct ParameterPack {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Valid1 {
+ DECLS
+};
+#else
+using TemplateTypeParmType::Valid1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+using TemplateTypeParmType::Invalid1;
+// expected-error at second.h:* {{'TemplateTypeParmType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateTypeParmType
namespace VarDecl {
#if defined(FIRST)
@@ -1381,46 +1880,36 @@ S9 s9;
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
-#if defined(FIRST)
-template <typename T>
-struct S {
- struct R {
- void foo(T x = 0) {}
- };
-};
-#elif defined(SECOND)
-template <typename T>
-struct S {
- struct R {
- void foo(T x = 1) {}
- };
+#define DECLS \
+ static int a; \
+ static I b; \
+ static const int c = 1; \
+ static constexpr int d = 5;
+
+#if defined(FIRST) || defined(SECOND)
+using I = int;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
};
#else
-void run() {
- S<int>::R().foo();
-}
-// expected-error at second.h:* {{'VarDecl::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
-// expected-note at first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
+Valid1 v1;
#endif
-#if defined(FIRST)
-template <typename alpha> struct Bravo {
- void charlie(bool delta = false) {}
-};
-typedef Bravo<char> echo;
-echo foxtrot;
-#elif defined(SECOND)
-template <typename alpha> struct Bravo {
- void charlie(bool delta = (false)) {}
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
};
-typedef Bravo<char> echo;
-echo foxtrot;
#else
-Bravo<char> golf;
-// expected-error at second.h:* {{'VarDecl::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
-// expected-note at first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
+Invalid1 i1;
+// expected-error at second.h:* {{'VarDecl::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
-}
+#undef DECLS
+} // namespace VarDecl
namespace Friend {
#if defined(FIRST)
@@ -1499,7 +1988,41 @@ S5 s5;
// expected-error at second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}}
// expected-note at first.h:* {{but in 'FirstModule' found friend function 'T5a'}}
#endif
-}
+
+#define DECLS \
+ friend class FriendA; \
+ friend struct FriendB; \
+ friend FriendC; \
+ friend const FriendD; \
+ friend void Function();
+
+#if defined(FIRST) || defined(SECOND)
+class FriendA {};
+class FriendB {};
+class FriendC {};
+class FriendD {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error at second.h:* {{'Friend::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace Friend
namespace TemplateParameters {
#if defined(FIRST)
@@ -1575,6 +2098,38 @@ using TemplateParameters::S6;
// expected-error at second.h:* {{'TemplateParameters::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found unnamed template parameter}}
// expected-note at first.h:* {{but in 'FirstModule' found template parameter 'A'}}
#endif
+
+#define DECLS
+
+#if defined(FIRST) || defined(SECOND)
+template <class> class DefaultArg;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <int, class, template <class> class,
+ int A, class B, template <int> class C,
+ int D = 1, class E = int, template <class F> class = DefaultArg>
+struct Valid1 {
+ DECLS
+};
+#else
+using TemplateParameters::Valid1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <int, class, template <class> class,
+ int A, class B, template <int> class C,
+ int D = 1, class E = int, template <class F> class = DefaultArg>
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+using TemplateParameters::Invalid1;
+// expected-error at second.h:* {{'TemplateParameters::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace TemplateParameters
namespace BaseClass {
@@ -1695,68 +2250,69 @@ S10 s10;
// expected-error at second.h:* {{'BaseClass::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B10a' with protected access specifier}}
// expected-note at first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B10a' with no access specifier}}
#endif
-} // namespace BaseClass
-// Interesting cases that should not cause errors. struct S should not error
-// while struct T should error at the access specifier mismatch at the end.
-namespace AllDecls {
-#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS) \
- typedef int INT; \
- struct NAME { \
- public: \
- private: \
- protected: \
- static_assert(1 == 1, "Message"); \
- static_assert(2 == 2); \
- \
- int x; \
- double y; \
- \
- INT z; \
- \
- unsigned a : 1; \
- unsigned b : 2 * 2 + 5 / 2; \
- \
- mutable int c = sizeof(x + y); \
- \
- void method() {} \
- static void static_method() {} \
- virtual void virtual_method() {} \
- virtual void pure_virtual_method() = 0; \
- inline void inline_method() {} \
- void volatile_method() volatile {} \
- void const_method() const {} \
- \
- typedef int typedef_int; \
- using using_int = int; \
- \
- void method_one_arg(int x) {} \
- void method_one_arg_default_argument(int x = 5 + 5) {} \
- void method_decayed_type(int x[5]) {} \
- \
- int constant_arr[5]; \
- \
- ACCESS: \
- };
+#define DECLS
-#if defined(FIRST)
-CREATE_ALL_DECL_STRUCT(S, public)
-#elif defined(SECOND)
-CREATE_ALL_DECL_STRUCT(S, public)
+#if defined(FIRST) || defined(SECOND)
+struct Base1 {};
+struct Base2 {};
+struct Base3 {};
+struct Base4 {};
+struct Base5 {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 :
+ Base1, virtual Base2, protected Base3, public Base4, private Base5 {
+
+ DECLS
+};
#else
-S *s;
+Valid1 v1;
#endif
-#if defined(FIRST)
-CREATE_ALL_DECL_STRUCT(T, private)
-#elif defined(SECOND)
-CREATE_ALL_DECL_STRUCT(T, public)
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 :
+ Base1, virtual Base2, protected Base3, public Base4, private Base5 {
+
+ DECLS
+ ACCESS
+};
#else
-T *t;
-// expected-error at second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
-// expected-note at first.h:* {{but in 'FirstModule' found private access specifier}}
+Invalid1 i1;
+// expected-error at second.h:* {{'BaseClass::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note at first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
+#undef DECLS
+} // namespace BaseClass
+
+
+// Collection of interesting cases below.
+
+// Naive parsing of AST can lead to cycles in processing. Ensure
+// self-references don't trigger an endless cycles of AST node processing.
+namespace SelfReference {
+#if defined(FIRST)
+template <template <int> class T> class Wrapper {};
+
+template <int N> class S {
+ S(Wrapper<::SelfReference::S> &Ref) {}
+};
+
+struct Xx {
+ struct Yy {
+ };
+};
+
+Xx::Xx::Xx::Yy yy;
+
+namespace NNS {
+template <typename> struct Foo;
+template <template <class> class T = NNS::Foo>
+struct NestedNamespaceSpecifier {};
}
+#endif
+} // namespace SelfReference
namespace FriendFunction {
#if defined(FIRST)
@@ -1825,7 +2381,7 @@ T t;
// expected-note at second.h:* {{but in 'SecondModule' found public access specifier}}
#endif
-} // namespace ImplicitDelc
+} // namespace ImplicitDecl
namespace TemplatedClass {
#if defined(FIRST)
@@ -2051,7 +2607,7 @@ void run() {
S<int>::R().foo();
}
#endif
-}
+} // namespace LateParsedDefaultArgument
namespace LateParsedDefaultArgument {
#if defined(FIRST)
@@ -2065,7 +2621,7 @@ Bravo<char> golf;
#elif defined(SECOND)
#else
#endif
-}
+} // LateParsedDefaultArgument
namespace DifferentParameterNameInTemplate {
#if defined(FIRST) || defined(SECOND)
@@ -2111,7 +2667,7 @@ struct BetaHelper {
#else
Alpha::Alpha() {}
#endif
-}
+} // DifferentParameterNameInTemplate
namespace ParameterTest {
#if defined(FIRST)
@@ -2138,7 +2694,7 @@ G* S<G>::Foo(const G* asdf, int*) {}
#else
S<X> s;
#endif
-}
+} // ParameterTest
namespace MultipleTypedefs {
#if defined(FIRST)
@@ -2188,12 +2744,59 @@ struct S3 {
#else
S3 s3;
#endif
+} // MultipleTypedefs
+
+namespace DefaultArguments {
+#if defined(FIRST)
+template <typename T>
+struct S {
+ struct R {
+ void foo(T x = 0) {}
+ };
+};
+#elif defined(SECOND)
+template <typename T>
+struct S {
+ struct R {
+ void foo(T x = 1) {}
+ };
+};
+#else
+void run() {
+ S<int>::R().foo();
}
+// expected-error at second.h:* {{'DefaultArguments::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
+#endif
+
+#if defined(FIRST)
+template <typename alpha> struct Bravo {
+ void charlie(bool delta = false) {}
+};
+typedef Bravo<char> echo;
+echo foxtrot;
+#elif defined(SECOND)
+template <typename alpha> struct Bravo {
+ void charlie(bool delta = (false)) {}
+};
+typedef Bravo<char> echo;
+echo foxtrot;
+#else
+Bravo<char> golf;
+// expected-error at second.h:* {{'DefaultArguments::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
+#endif
+} // namespace DefaultArguments
// Keep macros contained to one file.
#ifdef FIRST
#undef FIRST
#endif
+
#ifdef SECOND
#undef SECOND
#endif
+
+#ifdef ACCESS
+#undef ACCESS
+#endif
More information about the cfe-commits
mailing list