From 0333dd95636da52229ca14b4e5525c1cd8ba62d2 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 14 May 2019 18:51:07 +0000 Subject: [PATCH] Restore test files accidentally deleted in r354839 I think there must be a bug in git-llvm causing parent directories to be deleted when the diff deletes files in a subdirectory. Perhaps it is Windows-only. There has been a behavior change, so some of these tests now fail. I have marked them XFAIL and will fix them in a follow-up to separate the changes. llvm-svn: 360699 --- .../anonymous-fields/Inputs/anonymous-fields1.cpp | 5 + .../anonymous-fields/Inputs/anonymous-fields2.cpp | 9 ++ clang/test/ASTMerge/anonymous-fields/test.cpp | 4 + clang/test/ASTMerge/asm/Inputs/asm-function.cpp | 21 +++ clang/test/ASTMerge/asm/test.cpp | 8 ++ clang/test/ASTMerge/category/Inputs/category1.m | 48 +++++++ clang/test/ASTMerge/category/Inputs/category2.m | 49 +++++++ clang/test/ASTMerge/category/test.m | 13 ++ .../Inputs/class-template-partial-spec1.cpp | 118 +++++++++++++++++ .../Inputs/class-template-partial-spec2.cpp | 79 ++++++++++++ .../ASTMerge/class-template-partial-spec/test.cpp | 27 ++++ .../class-template/Inputs/class-template1.cpp | 37 ++++++ .../class-template/Inputs/class-template2.cpp | 37 ++++++ clang/test/ASTMerge/class-template/test.cpp | 30 +++++ clang/test/ASTMerge/class/Inputs/class1.cpp | 48 +++++++ clang/test/ASTMerge/class/Inputs/class2.cpp | 40 ++++++ clang/test/ASTMerge/class/test.cpp | 24 ++++ clang/test/ASTMerge/class2/Inputs/class3.cpp | 26 ++++ clang/test/ASTMerge/class2/test.cpp | 9 ++ clang/test/ASTMerge/codegen-body/Inputs/body1.c | 6 + clang/test/ASTMerge/codegen-body/Inputs/body2.c | 4 + clang/test/ASTMerge/codegen-body/test.c | 5 + clang/test/ASTMerge/codegen-exprs/Inputs/exprs1.c | 10 ++ clang/test/ASTMerge/codegen-exprs/Inputs/exprs2.c | 10 ++ clang/test/ASTMerge/codegen-exprs/test.c | 5 + clang/test/ASTMerge/enum/Inputs/enum1.c | 42 ++++++ clang/test/ASTMerge/enum/Inputs/enum2.c | 42 ++++++ clang/test/ASTMerge/enum/test.c | 27 ++++ clang/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp | 141 +++++++++++++++++++++ clang/test/ASTMerge/exprs-cpp/test.cpp | 50 ++++++++ clang/test/ASTMerge/exprs/Inputs/exprs1.c | 10 ++ clang/test/ASTMerge/exprs/Inputs/exprs2.c | 10 ++ clang/test/ASTMerge/exprs/test.c | 5 + .../ASTMerge/function-cpp/Inputs/function-1.cpp | 8 ++ clang/test/ASTMerge/function-cpp/test.cpp | 10 ++ clang/test/ASTMerge/function/Inputs/function1.c | 6 + clang/test/ASTMerge/function/Inputs/function2.c | 7 + clang/test/ASTMerge/function/test.c | 17 +++ .../inheritance/Inputs/inheritance-base.cpp | 7 + clang/test/ASTMerge/inheritance/test.cpp | 8 ++ .../init-ctors/Inputs/init-ctors-classes.cpp | 19 +++ clang/test/ASTMerge/init-ctors/test.cpp | 10 ++ .../injected-class-name-decl/Inputs/inject1.cpp | 2 + .../injected-class-name-decl/Inputs/inject2.cpp | 2 + .../ASTMerge/injected-class-name-decl/test.cpp | 3 + clang/test/ASTMerge/interface/Inputs/interface1.m | 105 +++++++++++++++ clang/test/ASTMerge/interface/Inputs/interface2.m | 100 +++++++++++++++ clang/test/ASTMerge/interface/test.m | 24 ++++ clang/test/ASTMerge/macro/Inputs/macro.modulemap | 4 + clang/test/ASTMerge/macro/Inputs/macro1.h | 5 + clang/test/ASTMerge/macro/Inputs/macro1.m | 5 + clang/test/ASTMerge/macro/Inputs/macro2.m | 5 + clang/test/ASTMerge/macro/test.m | 6 + .../test/ASTMerge/namespace/Inputs/namespace1.cpp | 27 ++++ .../test/ASTMerge/namespace/Inputs/namespace2.cpp | 60 +++++++++ clang/test/ASTMerge/namespace/test.cpp | 19 +++ clang/test/ASTMerge/property/Inputs/property1.m | 31 +++++ clang/test/ASTMerge/property/Inputs/property2.m | 33 +++++ clang/test/ASTMerge/property/test.m | 15 +++ .../ASTMerge/std-initializer-list/Inputs/il.cpp | 9 ++ clang/test/ASTMerge/std-initializer-list/test.cpp | 3 + clang/test/ASTMerge/struct/Inputs/struct1.c | 141 +++++++++++++++++++++ clang/test/ASTMerge/struct/Inputs/struct2.c | 138 ++++++++++++++++++++ clang/test/ASTMerge/struct/test.c | 57 +++++++++ clang/test/ASTMerge/typedef/Inputs/typedef1.c | 4 + clang/test/ASTMerge/typedef/Inputs/typedef2.c | 4 + clang/test/ASTMerge/typedef/test.c | 9 ++ clang/test/ASTMerge/unnamed_fields/Inputs/il.cpp | 3 + clang/test/ASTMerge/unnamed_fields/test.cpp | 3 + clang/test/ASTMerge/var-cpp/Inputs/var1.cpp | 17 +++ clang/test/ASTMerge/var-cpp/test.cpp | 9 ++ clang/test/ASTMerge/var/Inputs/var1.c | 7 + clang/test/ASTMerge/var/Inputs/var1.h | 1 + clang/test/ASTMerge/var/Inputs/var2.c | 7 + clang/test/ASTMerge/var/test.c | 14 ++ 75 files changed, 1963 insertions(+) create mode 100644 clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp create mode 100644 clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp create mode 100644 clang/test/ASTMerge/anonymous-fields/test.cpp create mode 100644 clang/test/ASTMerge/asm/Inputs/asm-function.cpp create mode 100644 clang/test/ASTMerge/asm/test.cpp create mode 100644 clang/test/ASTMerge/category/Inputs/category1.m create mode 100644 clang/test/ASTMerge/category/Inputs/category2.m create mode 100644 clang/test/ASTMerge/category/test.m create mode 100644 clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp create mode 100644 clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp create mode 100644 clang/test/ASTMerge/class-template-partial-spec/test.cpp create mode 100644 clang/test/ASTMerge/class-template/Inputs/class-template1.cpp create mode 100644 clang/test/ASTMerge/class-template/Inputs/class-template2.cpp create mode 100644 clang/test/ASTMerge/class-template/test.cpp create mode 100644 clang/test/ASTMerge/class/Inputs/class1.cpp create mode 100644 clang/test/ASTMerge/class/Inputs/class2.cpp create mode 100644 clang/test/ASTMerge/class/test.cpp create mode 100644 clang/test/ASTMerge/class2/Inputs/class3.cpp create mode 100644 clang/test/ASTMerge/class2/test.cpp create mode 100644 clang/test/ASTMerge/codegen-body/Inputs/body1.c create mode 100644 clang/test/ASTMerge/codegen-body/Inputs/body2.c create mode 100644 clang/test/ASTMerge/codegen-body/test.c create mode 100644 clang/test/ASTMerge/codegen-exprs/Inputs/exprs1.c create mode 100644 clang/test/ASTMerge/codegen-exprs/Inputs/exprs2.c create mode 100644 clang/test/ASTMerge/codegen-exprs/test.c create mode 100644 clang/test/ASTMerge/enum/Inputs/enum1.c create mode 100644 clang/test/ASTMerge/enum/Inputs/enum2.c create mode 100644 clang/test/ASTMerge/enum/test.c create mode 100644 clang/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp create mode 100644 clang/test/ASTMerge/exprs-cpp/test.cpp create mode 100644 clang/test/ASTMerge/exprs/Inputs/exprs1.c create mode 100644 clang/test/ASTMerge/exprs/Inputs/exprs2.c create mode 100644 clang/test/ASTMerge/exprs/test.c create mode 100644 clang/test/ASTMerge/function-cpp/Inputs/function-1.cpp create mode 100644 clang/test/ASTMerge/function-cpp/test.cpp create mode 100644 clang/test/ASTMerge/function/Inputs/function1.c create mode 100644 clang/test/ASTMerge/function/Inputs/function2.c create mode 100644 clang/test/ASTMerge/function/test.c create mode 100644 clang/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp create mode 100644 clang/test/ASTMerge/inheritance/test.cpp create mode 100644 clang/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp create mode 100644 clang/test/ASTMerge/init-ctors/test.cpp create mode 100644 clang/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp create mode 100644 clang/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp create mode 100644 clang/test/ASTMerge/injected-class-name-decl/test.cpp create mode 100644 clang/test/ASTMerge/interface/Inputs/interface1.m create mode 100644 clang/test/ASTMerge/interface/Inputs/interface2.m create mode 100644 clang/test/ASTMerge/interface/test.m create mode 100644 clang/test/ASTMerge/macro/Inputs/macro.modulemap create mode 100644 clang/test/ASTMerge/macro/Inputs/macro1.h create mode 100644 clang/test/ASTMerge/macro/Inputs/macro1.m create mode 100644 clang/test/ASTMerge/macro/Inputs/macro2.m create mode 100644 clang/test/ASTMerge/macro/test.m create mode 100644 clang/test/ASTMerge/namespace/Inputs/namespace1.cpp create mode 100644 clang/test/ASTMerge/namespace/Inputs/namespace2.cpp create mode 100644 clang/test/ASTMerge/namespace/test.cpp create mode 100644 clang/test/ASTMerge/property/Inputs/property1.m create mode 100644 clang/test/ASTMerge/property/Inputs/property2.m create mode 100644 clang/test/ASTMerge/property/test.m create mode 100644 clang/test/ASTMerge/std-initializer-list/Inputs/il.cpp create mode 100644 clang/test/ASTMerge/std-initializer-list/test.cpp create mode 100644 clang/test/ASTMerge/struct/Inputs/struct1.c create mode 100644 clang/test/ASTMerge/struct/Inputs/struct2.c create mode 100644 clang/test/ASTMerge/struct/test.c create mode 100644 clang/test/ASTMerge/typedef/Inputs/typedef1.c create mode 100644 clang/test/ASTMerge/typedef/Inputs/typedef2.c create mode 100644 clang/test/ASTMerge/typedef/test.c create mode 100644 clang/test/ASTMerge/unnamed_fields/Inputs/il.cpp create mode 100644 clang/test/ASTMerge/unnamed_fields/test.cpp create mode 100644 clang/test/ASTMerge/var-cpp/Inputs/var1.cpp create mode 100644 clang/test/ASTMerge/var-cpp/test.cpp create mode 100644 clang/test/ASTMerge/var/Inputs/var1.c create mode 100644 clang/test/ASTMerge/var/Inputs/var1.h create mode 100644 clang/test/ASTMerge/var/Inputs/var2.c create mode 100644 clang/test/ASTMerge/var/test.c diff --git a/clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp b/clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp new file mode 100644 index 0000000..829bc0e --- /dev/null +++ b/clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp @@ -0,0 +1,5 @@ +class A { +public: + struct { int foo; } f; + struct { int foo; } g; +}; diff --git a/clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp b/clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp new file mode 100644 index 0000000..28ea46d --- /dev/null +++ b/clang/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp @@ -0,0 +1,9 @@ +class A { +public: + struct { int foo; } f; + struct { int foo; } g; +}; + +inline int useA(A &a) { + return (a.f.foo + a.g.foo); +} diff --git a/clang/test/ASTMerge/anonymous-fields/test.cpp b/clang/test/ASTMerge/anonymous-fields/test.cpp new file mode 100644 index 0000000..67afc29 --- /dev/null +++ b/clang/test/ASTMerge/anonymous-fields/test.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/anonymous-fields1.cpp +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/anonymous-fields2.cpp +// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast %s +// expected-no-diagnostics diff --git a/clang/test/ASTMerge/asm/Inputs/asm-function.cpp b/clang/test/ASTMerge/asm/Inputs/asm-function.cpp new file mode 100644 index 0000000..1b87833 --- /dev/null +++ b/clang/test/ASTMerge/asm/Inputs/asm-function.cpp @@ -0,0 +1,21 @@ + +unsigned char asmFunc(unsigned char a, unsigned char b) { + unsigned int la = a; + unsigned int lb = b; + unsigned int bigres; + unsigned char res; + __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) : + "edx", "cc"); + res = bigres; + return res; +} + +int asmFunc2(int i) { + int res; + asm ("mov %1, %0 \t\n" + "inc %0 " + : "=r" (res) + : "r" (i) + : "cc"); + return res; +} diff --git a/clang/test/ASTMerge/asm/test.cpp b/clang/test/ASTMerge/asm/test.cpp new file mode 100644 index 0000000..8c3bdfe --- /dev/null +++ b/clang/test/ASTMerge/asm/test.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/asm-function.cpp +// RUN: %clang_cc1 -triple i386-unknown-unknown -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +void testAsmImport() { + asmFunc(12, 42); + asmFunc2(42); +} diff --git a/clang/test/ASTMerge/category/Inputs/category1.m b/clang/test/ASTMerge/category/Inputs/category1.m new file mode 100644 index 0000000..afcaab8 --- /dev/null +++ b/clang/test/ASTMerge/category/Inputs/category1.m @@ -0,0 +1,48 @@ +@interface I1 +@end + +// Matching category +@interface I1 (Cat1) +- (int)method0; +@end + +// Matching class extension +@interface I1 () +- (int)method1; +@end + +// Mismatched category +@interface I1 (Cat2) +- (int)method2; +@end + +@interface I2 +@end + +// Mismatched class extension +@interface I2 () +- (int)method3; +@end + +// Category with implementation +@interface I2 (Cat3) +@end + +@implementation I2 (Cat3) +@end + +// Category with implementation +@interface I2 (Cat4) +@end + +@implementation I2 (Cat4) +@end + +// Category with mismatched implementation +@interface I2 (Cat6) +@end + +@implementation I2 (Cat6) +- (float)blah { return 0; } +@end + diff --git a/clang/test/ASTMerge/category/Inputs/category2.m b/clang/test/ASTMerge/category/Inputs/category2.m new file mode 100644 index 0000000..49a3c27 --- /dev/null +++ b/clang/test/ASTMerge/category/Inputs/category2.m @@ -0,0 +1,49 @@ +typedef int Int; + +@interface I1 +@end + +// Matching category +@interface I1 (Cat1) +- (Int)method0; +@end + +// Matching class extension +@interface I1 () +- (Int)method1; +@end + +// Mismatched category +@interface I1 (Cat2) +- (float)method2; +@end + +@interface I2 +@end + +// Mismatched class extension +@interface I2 () +- (float)method3; +@end + +// Category with implementation +@interface I2 (Cat3) +@end + +@implementation I2 (Cat3) +@end + +// Category with implementation +@interface I2 (Cat5) +@end + +@implementation I2 (Cat5) +@end + +// Category with mismatched implementation +@interface I2 (Cat6) +@end + +@implementation I2 (Cat6) +- (int)blah { return 0; } +@end diff --git a/clang/test/ASTMerge/category/test.m b/clang/test/ASTMerge/category/test.m new file mode 100644 index 0000000..bee72f6 --- /dev/null +++ b/clang/test/ASTMerge/category/test.m @@ -0,0 +1,13 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/category1.m +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/category2.m +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: category2.m:18:1: error: instance method 'method2' has incompatible result types in different translation units ('float' vs. 'int') +// CHECK: category1.m:16:1: note: instance method 'method2' also declared here +// CHECK: category2.m:26:1: error: instance method 'method3' has incompatible result types in different translation units ('float' vs. 'int') +// CHECK: category1.m:24:1: note: instance method 'method3' also declared here +// CHECK: category2.m:48:1: error: instance method 'blah' has incompatible result types in different translation units ('int' vs. 'float') +// CHECK: category1.m:46:1: note: instance method 'blah' also declared here +// CHECK: 3 errors generated. diff --git a/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp b/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp new file mode 100644 index 0000000..43606d4 --- /dev/null +++ b/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp @@ -0,0 +1,118 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleSource; +TwoOptionTemplate SecondDoubleSource; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + int member; + static constexpr int val = I; +}; + +template +struct IntTemplateSpec { + char member; + static constexpr int val = I; +}; + +IntTemplateSpec<4, wchar_t> Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, long> Y2; +IntTemplateSpec<3, int> Y3; +//template constexpr int IntTemplateSpec::val; +IntTemplateSpec<42, double> NumberSource; +static_assert(NumberSource.val == 42); + +namespace One { +namespace Two { + // Just an empty namespace to ensure we can deal with multiple namespace decls. +} +} + + +namespace One { +namespace Two { +namespace Three { + +template +class Parent {}; + +} // namespace Three + +} // namespace Two + +template +struct Child1: public Two::Three::Parent { + char member; +}; + +template +struct Child1> { + T member; +}; + +} // namespace One + +One::Child1 Z0Source; + +// Test import of nested namespace specifiers +template +struct Outer { + template class Inner0; +}; + +template +template +class Outer::Inner0 { +public: + void f(X, Y); + template struct Inner1; +}; + +template +template +void Outer::Inner0::f(X, Y) {} + +template +template +template +class Outer::Inner0::Inner1 { +public: + void f(Y, Z); +}; + +template +template +template +void Outer::Inner0::Inner1::f(Y, Z) {} diff --git a/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp b/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp new file mode 100644 index 0000000..2f3f0c6 --- /dev/null +++ b/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp @@ -0,0 +1,79 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleDest; +TwoOptionTemplate SecondDoubleDest; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + double member; + static constexpr int val = I; +}; + +template +struct IntTemplateSpec { + char member; + static constexpr int val = I; +}; + +IntTemplateSpec<4, wchar_t>Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, int> Y2; +IntTemplateSpec<2, int> Y3; +IntTemplateSpec<43, double> NumberDest; + +namespace One { +namespace Two { +namespace Three { + +template +class Parent {}; + +} // namespace Three + +} // namespace Two + +template +struct Child1: public Two::Three::Parent { + char member; +}; + +template +struct Child1> { + T member; +}; + +} // namespace One + +namespace Dst { One::Child1> Z0Dst; } +One::Child1 Z1; diff --git a/clang/test/ASTMerge/class-template-partial-spec/test.cpp b/clang/test/ASTMerge/class-template-partial-spec/test.cpp new file mode 100644 index 0000000..9aa4ab5 --- /dev/null +++ b/clang/test/ASTMerge/class-template-partial-spec/test.cpp @@ -0,0 +1,27 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp +// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member)); +static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member)); +static_assert(NumberSource.val == 42); +static_assert(sizeof(Z0Source.member) == sizeof(char)); +static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double)); +static_assert(sizeof(One::Child1>::member) == sizeof(double)); + +// CHECK: class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' + +// CHECK: class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' + +// CHECK: class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units +// CHECK: class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here +// CHECK: class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here + +// CHECK: class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') +// CHECK: class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' + +// CHECK-NOT: static_assert diff --git a/clang/test/ASTMerge/class-template/Inputs/class-template1.cpp b/clang/test/ASTMerge/class-template/Inputs/class-template1.cpp new file mode 100644 index 0000000..fb5b229 --- /dev/null +++ b/clang/test/ASTMerge/class-template/Inputs/class-template1.cpp @@ -0,0 +1,37 @@ +template +struct X0 { + T getValue(T arg) { return arg; } +}; + +template +struct X1; + +template +struct X2; + +template +struct X3; + +template class> +struct X4; + +template class> +struct X5; + +template +struct X6; + +extern X0 *x0i; +extern X0 *x0l; +extern X0 *x0r; + +template<> +struct X0 { + int member; + char getValue(char ch) { return static_cast(member); } +}; + +template<> +struct X0 { + int member; +}; diff --git a/clang/test/ASTMerge/class-template/Inputs/class-template2.cpp b/clang/test/ASTMerge/class-template/Inputs/class-template2.cpp new file mode 100644 index 0000000..b5d0add --- /dev/null +++ b/clang/test/ASTMerge/class-template/Inputs/class-template2.cpp @@ -0,0 +1,37 @@ +template +struct X0 { + T getValue(T arg); +}; + +template +struct X1; + +template +struct X2; + +template +struct X3; + +template class> +struct X4; + +template class> +struct X5; + +template class> +struct X6; + +typedef int Integer; +extern X0 *x0i; +extern X0 *x0f; +extern X0 *x0r; + +template<> +struct X0 { + int member; +}; + +template<> +struct X0 { + float member; +}; diff --git a/clang/test/ASTMerge/class-template/test.cpp b/clang/test/ASTMerge/class-template/test.cpp new file mode 100644 index 0000000..f2ac4c5 --- /dev/null +++ b/clang/test/ASTMerge/class-template/test.cpp @@ -0,0 +1,30 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class-template1.cpp +// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.2.ast %S/Inputs/class-template2.cpp +// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +static_assert(sizeof(X0().getValue(1)) == sizeof(char)); +static_assert(sizeof(X0().getValue(1)) == sizeof(int)); + +// CHECK: class-template1.cpp:9:14: error: non-type template parameter declared with incompatible types in different translation units ('int' vs. 'long') +// CHECK: class-template2.cpp:9:15: note: declared here with type 'long' + +// CHECK: class-template1.cpp:12:14: error: template parameter has different kinds in different translation units +// CHECK: class-template2.cpp:12:10: note: template parameter declared here + +// CHECK: class-template1.cpp:18:23: error: non-type template parameter declared with incompatible types in different translation units ('long' vs. 'int') +// CHECK: class-template2.cpp:18:23: note: declared here with type 'int' + +// CHECK: class-template1.cpp:21:10: error: template parameter has different kinds in different translation units +// CHECK: class-template2.cpp:21:10: note: template parameter declared here + +// CHECK: class-template2.cpp:27:20: error: external variable 'x0r' declared with incompatible types in different translation units ('X0 *' vs. 'X0 *') +// CHECK: class-template1.cpp:26:19: note: declared here with type 'X0 *' + +// CHECK: class-template1.cpp:35:8: warning: type 'X0' has incompatible definitions in different translation units +// CHECK: class-template1.cpp:36:7: note: field 'member' has type 'int' here +// CHECK: class-template2.cpp:36:9: note: field 'member' has type 'float' here + +// CHECK: 1 warning and 5 errors generated. +// CHECK-NOT: static_assert diff --git a/clang/test/ASTMerge/class/Inputs/class1.cpp b/clang/test/ASTMerge/class/Inputs/class1.cpp new file mode 100644 index 0000000..2bd5503 --- /dev/null +++ b/clang/test/ASTMerge/class/Inputs/class1.cpp @@ -0,0 +1,48 @@ +struct A { + public: + int x; +}; + +struct B : A { + float y; + float foo(); +}; + +struct C { + C(int i = 10); + C(const C&); + C &operator=(C&); + ~C(); +}; + +enum E { + b = 1 +}; + +//Friend import tests +void f(); +int g(int a); +struct X; +struct Y; + +struct F1 { +public: + int x; + friend struct X; + friend int g(int); + friend void f(); +}; + +struct F2 { +public: + int x; + friend struct X; + friend void f(); +}; + +struct F3 { +public: + int x; + friend int g(int); + friend void f(); +}; diff --git a/clang/test/ASTMerge/class/Inputs/class2.cpp b/clang/test/ASTMerge/class/Inputs/class2.cpp new file mode 100644 index 0000000..6fe38b9 --- /dev/null +++ b/clang/test/ASTMerge/class/Inputs/class2.cpp @@ -0,0 +1,40 @@ +struct A { + public: + int x; +}; + +struct B : A { + int y; + int foo(); +}; + +enum E { + a = 0, + b = 1 +}; + +//Friend import tests +void f(); +int g(int a); +struct X; +struct Y; + +struct F1 { +public: + int x; + friend struct X; + friend int g(int); + friend void f(); +}; + +struct F2 { +public: + int x; + friend struct X; +}; + +struct F3 { +public: + int x; + friend void f(); +}; diff --git a/clang/test/ASTMerge/class/test.cpp b/clang/test/ASTMerge/class/test.cpp new file mode 100644 index 0000000..ba553af --- /dev/null +++ b/clang/test/ASTMerge/class/test.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/class1.cpp +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/class2.cpp +// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 -Wno-odr -Werror + +// CHECK: class1.cpp:6:8: warning: type 'B' has incompatible definitions in different translation units +// CHECK: class1.cpp:7:9: note: field 'y' has type 'float' here +// CHECK: class2.cpp:7:7: note: field 'y' has type 'int' here + +// FIXME: we should also complain about mismatched types on the method + +// CHECK: class1.cpp:18:6: warning: type 'E' has incompatible definitions in different translation units +// CHECK: class1.cpp:19:3: note: enumerator 'b' with value 1 here +// CHECK: class2.cpp:12:3: note: enumerator 'a' with value 0 here + +// CHECK: class1.cpp:43:8: warning: type 'F3' has incompatible definitions in different translation units +// CHECK: class1.cpp:46:3: note: friend declared here +// CHECK: class2.cpp:36:8: note: no corresponding friend here + +// CHECK: class1.cpp:36:8: warning: type 'F2' has incompatible definitions in different translation units +// CHECK: class1.cpp:39:3: note: friend declared here +// CHECK: class2.cpp:30:8: note: no corresponding friend here + +// CHECK: 4 warnings generated. diff --git a/clang/test/ASTMerge/class2/Inputs/class3.cpp b/clang/test/ASTMerge/class2/Inputs/class3.cpp new file mode 100644 index 0000000..428acc3 --- /dev/null +++ b/clang/test/ASTMerge/class2/Inputs/class3.cpp @@ -0,0 +1,26 @@ +class C1 { +public: + C1(); + ~C1(); + C1 *method_1() { + return this; + } + C1 method_2() { + return C1(); + } + void method_3() { + const C1 &ref = C1(); + } +}; + +class C11 : public C1 { +}; + +class C2 { +private: + int x; + friend class C3; +public: + static_assert(sizeof(x) == sizeof(int), "Error"); + typedef class C2::C2 InjType; +}; diff --git a/clang/test/ASTMerge/class2/test.cpp b/clang/test/ASTMerge/class2/test.cpp new file mode 100644 index 0000000..6021403 --- /dev/null +++ b/clang/test/ASTMerge/class2/test.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { + return x->x; + } +}; diff --git a/clang/test/ASTMerge/codegen-body/Inputs/body1.c b/clang/test/ASTMerge/codegen-body/Inputs/body1.c new file mode 100644 index 0000000..d4d1e4b --- /dev/null +++ b/clang/test/ASTMerge/codegen-body/Inputs/body1.c @@ -0,0 +1,6 @@ +int f(); + +int main() +{ + return f(); +} diff --git a/clang/test/ASTMerge/codegen-body/Inputs/body2.c b/clang/test/ASTMerge/codegen-body/Inputs/body2.c new file mode 100644 index 0000000..73cb1ed --- /dev/null +++ b/clang/test/ASTMerge/codegen-body/Inputs/body2.c @@ -0,0 +1,4 @@ +__inline__ __attribute__ ((always_inline)) int f() +{ + return 2; +} diff --git a/clang/test/ASTMerge/codegen-body/test.c b/clang/test/ASTMerge/codegen-body/test.c new file mode 100644 index 0000000..7232bf4 --- /dev/null +++ b/clang/test/ASTMerge/codegen-body/test.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/body1.c +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/body2.c +// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast %s +// expected-no-diagnostics + diff --git a/clang/test/ASTMerge/codegen-exprs/Inputs/exprs1.c b/clang/test/ASTMerge/codegen-exprs/Inputs/exprs1.c new file mode 100644 index 0000000..1c268da --- /dev/null +++ b/clang/test/ASTMerge/codegen-exprs/Inputs/exprs1.c @@ -0,0 +1,10 @@ +// Matching +enum E0 { + E0_Val0 = 'a', + E0_Val1 = (17), + E0_Val2 = (1 << 2), + E0_Val3 = E0_Val2, + E0_Val4 = sizeof(int*), + E0_Val5 = (unsigned int)-1 +}; + diff --git a/clang/test/ASTMerge/codegen-exprs/Inputs/exprs2.c b/clang/test/ASTMerge/codegen-exprs/Inputs/exprs2.c new file mode 100644 index 0000000..1c268da --- /dev/null +++ b/clang/test/ASTMerge/codegen-exprs/Inputs/exprs2.c @@ -0,0 +1,10 @@ +// Matching +enum E0 { + E0_Val0 = 'a', + E0_Val1 = (17), + E0_Val2 = (1 << 2), + E0_Val3 = E0_Val2, + E0_Val4 = sizeof(int*), + E0_Val5 = (unsigned int)-1 +}; + diff --git a/clang/test/ASTMerge/codegen-exprs/test.c b/clang/test/ASTMerge/codegen-exprs/test.c new file mode 100644 index 0000000..b5069f9 --- /dev/null +++ b/clang/test/ASTMerge/codegen-exprs/test.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.1.ast %S/Inputs/exprs1.c +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.2.ast %S/Inputs/exprs2.c +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s +// expected-no-diagnostics + diff --git a/clang/test/ASTMerge/enum/Inputs/enum1.c b/clang/test/ASTMerge/enum/Inputs/enum1.c new file mode 100644 index 0000000..f2b9c5c --- /dev/null +++ b/clang/test/ASTMerge/enum/Inputs/enum1.c @@ -0,0 +1,42 @@ +// Matching +enum E1 { + E1Enumerator1, + E1Enumerator2 = 3, + E1Enumerator3 +} x1; + +// Value mismatch +enum E2 { + E2Enumerator1, + E2Enumerator2 = 3, + E2Enumerator3 +} x2; + +// Name mismatch +enum E3 { + E3Enumerator1, + E3Enumerator2 = 3, + E3Enumerator3 +} x3; + +// Missing enumerator +enum E4 { + E4Enumerator1, + E4Enumerator2, + E4Enumerator3 +} x4; + +// Extra enumerator +enum E5 { + E5Enumerator1, + E5Enumerator2, + E5Enumerator3 +} x5; + +// Matching, with typedef +typedef enum { + E6Enumerator1, + E6Enumerator2 +} E6; + +E6 x6; diff --git a/clang/test/ASTMerge/enum/Inputs/enum2.c b/clang/test/ASTMerge/enum/Inputs/enum2.c new file mode 100644 index 0000000..315b4dc --- /dev/null +++ b/clang/test/ASTMerge/enum/Inputs/enum2.c @@ -0,0 +1,42 @@ +// Matching +enum E1 { + E1Enumerator1, + E1Enumerator2 = 3, + E1Enumerator3 +} x1; + +// Value mismatch +enum E2 { + E2Enumerator1, + E2Enumerator2 = 4, + E2Enumerator3 +} x2; + +// Name mismatch +enum E3 { + E3Enumerator1, + E3Enumerator = 3, + E3Enumerator3 +} x3; + +// Missing enumerator +enum E4 { + E4Enumerator1, + E4Enumerator2 +} x4; + +// Extra enumerator +enum E5 { + E5Enumerator1, + E5Enumerator2, + E5Enumerator3, + E5Enumerator4 +} x5; + +// Matching, with typedef +typedef enum { + E6Enumerator1, + E6Enumerator2 +} E6; + +E6 x6; diff --git a/clang/test/ASTMerge/enum/test.c b/clang/test/ASTMerge/enum/test.c new file mode 100644 index 0000000..57f9278 --- /dev/null +++ b/clang/test/ASTMerge/enum/test.c @@ -0,0 +1,27 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/enum1.c +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/enum2.c +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: enum1.c:9:6: warning: type 'enum E2' has incompatible definitions in different translation units +// CHECK: enum1.c:11:3: note: enumerator 'E2Enumerator2' with value 3 here +// CHECK: enum2.c:11:3: note: enumerator 'E2Enumerator2' with value 4 here +// CHECK: enum2.c:13:3: error: external variable 'x2' declared with incompatible types in different translation units ('enum E2' vs. 'enum E2') +// CHECK: enum1.c:13:3: note: declared here with type 'enum E2' +// CHECK: enum1.c:16:6: warning: type 'enum E3' has incompatible definitions in different translation units +// CHECK: enum1.c:18:3: note: enumerator 'E3Enumerator2' with value 3 here +// CHECK: enum2.c:18:3: note: enumerator 'E3Enumerator' with value 3 here +// CHECK: enum2.c:20:3: error: external variable 'x3' declared with incompatible types in different translation units ('enum E3' vs. 'enum E3') +// CHECK: enum1.c:20:3: note: declared here with type 'enum E3' +// CHECK: enum1.c:23:6: warning: type 'enum E4' has incompatible definitions in different translation units +// CHECK: enum1.c:26:3: note: enumerator 'E4Enumerator3' with value 2 here +// CHECK: enum2.c:23:6: note: no corresponding enumerator here +// CHECK: enum2.c:26:3: error: external variable 'x4' declared with incompatible types in different translation units ('enum E4' vs. 'enum E4') +// CHECK: enum1.c:27:3: note: declared here with type 'enum E4' +// CHECK: enum1.c:30:6: warning: type 'enum E5' has incompatible definitions in different translation units +// CHECK: enum2.c:33:3: note: enumerator 'E5Enumerator4' with value 3 here +// CHECK: enum1.c:30:6: note: no corresponding enumerator here +// CHECK: enum2.c:34:3: error: external variable 'x5' declared with incompatible types in different translation units ('enum E5' vs. 'enum E5') +// CHECK: enum1.c:34:3: note: declared here with type 'enum E5' +// CHECK: 4 warnings and 4 errors generated diff --git a/clang/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp b/clang/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp new file mode 100644 index 0000000..6fdc33f --- /dev/null +++ b/clang/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp @@ -0,0 +1,141 @@ +// Integer literals +const char Ch1 = 'a'; +const signed char Ch2 = 'b'; +const unsigned char Ch3 = 'c'; + +const wchar_t Ch4 = L'd'; +const signed wchar_t Ch5 = L'e'; +const unsigned wchar_t Ch6 = L'f'; + +const short C1 = 12; +const unsigned short C2 = 13; + +const int C3 = 12; +const unsigned int C4 = 13; + +const long C5 = 22; +const unsigned long C6 = 23; + +const long long C7 = 66; +const unsigned long long C8 = 67; + + +// String literals +const char str1[] = "ABCD"; +const char str2[] = "ABCD" "0123"; + +const wchar_t wstr1[] = L"DEF"; +const wchar_t wstr2[] = L"DEF" L"123"; + + +// Boolean literals +const bool bval1 = true; +const bool bval2 = false; + +// Floating Literals +const float F1 = 12.2F; +const double F2 = 1E4; +const long double F3 = 1.2E-3L; + + +// nullptr literal +const void *vptr = nullptr; + + +int glb_1[4] = { 10, 20, 30, 40 }; + +struct S1 { + int a; + int b[3]; +}; + +struct S2 { + int c; + S1 d; +}; + +S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 }; + +void testNewThrowDelete() { + throw; + char *p = new char[10]; + delete[] p; +} + +int testArrayElement(int *x, int n) { + return x[n]; +} + +int testTernaryOp(int c, int x, int y) { + return c ? x : y; +} + +S1 &testConstCast(const S1 &x) { + return const_cast(x); +} + +S1 &testStaticCast(S1 &x) { + return static_cast(x); +} + +S1 &testReinterpretCast(S1 &x) { + return reinterpret_cast(x); +} + +S1 &testDynamicCast(S1 &x) { + return dynamic_cast(x); +} + +int testScalarInit(int x) { + return int(x); +} + +struct S { + float f; + double d; +}; +struct T { + int i; + struct S s[10]; +}; + +void testOffsetOf() { + __builtin_offsetof(struct T, s[2].d); +} + + +int testDefaultArg(int a = 2*2) { + return a; +} + +int testDefaultArgExpr() { + return testDefaultArg(); +} + +template // T has TemplateTypeParmType +void testTemplateTypeParmType(int i); + +void useTemplateType() { + testTemplateTypeParmType(4); +} + +const bool ExpressionTrait = __is_lvalue_expr(1); +const unsigned ArrayRank = __array_rank(int[10][20]); +const unsigned ArrayExtent = __array_extent(int[10][20], 1); + +constexpr int testLambdaAdd(int toAdd) { + const int Captured1 = 1, Captured2 = 2; + constexpr auto LambdaAdd = [Captured1, Captured2](int k) -> int { + return Captured1 + Captured2 + k; + }; + return LambdaAdd(toAdd); +} + +template +struct TestLambdaTemplate { + T i, j; + TestLambdaTemplate(T i, const T &j) : i(i), j(j) {} + T testLambda(T k) { + return [this](T k) -> decltype(auto) { return i + j + k; }(k); + } +}; diff --git a/clang/test/ASTMerge/exprs-cpp/test.cpp b/clang/test/ASTMerge/exprs-cpp/test.cpp new file mode 100644 index 0000000..c0b282e --- /dev/null +++ b/clang/test/ASTMerge/exprs-cpp/test.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +static_assert(testLambdaAdd(3) == 6); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + testDefaultArg(); + testDefaultArgExpr(); + useTemplateType(); + TestLambdaTemplate(1, 2).testLambda(3); +} diff --git a/clang/test/ASTMerge/exprs/Inputs/exprs1.c b/clang/test/ASTMerge/exprs/Inputs/exprs1.c new file mode 100644 index 0000000..1c268da --- /dev/null +++ b/clang/test/ASTMerge/exprs/Inputs/exprs1.c @@ -0,0 +1,10 @@ +// Matching +enum E0 { + E0_Val0 = 'a', + E0_Val1 = (17), + E0_Val2 = (1 << 2), + E0_Val3 = E0_Val2, + E0_Val4 = sizeof(int*), + E0_Val5 = (unsigned int)-1 +}; + diff --git a/clang/test/ASTMerge/exprs/Inputs/exprs2.c b/clang/test/ASTMerge/exprs/Inputs/exprs2.c new file mode 100644 index 0000000..1c268da --- /dev/null +++ b/clang/test/ASTMerge/exprs/Inputs/exprs2.c @@ -0,0 +1,10 @@ +// Matching +enum E0 { + E0_Val0 = 'a', + E0_Val1 = (17), + E0_Val2 = (1 << 2), + E0_Val3 = E0_Val2, + E0_Val4 = sizeof(int*), + E0_Val5 = (unsigned int)-1 +}; + diff --git a/clang/test/ASTMerge/exprs/test.c b/clang/test/ASTMerge/exprs/test.c new file mode 100644 index 0000000..7495bb6 --- /dev/null +++ b/clang/test/ASTMerge/exprs/test.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.1.ast %S/Inputs/exprs1.c +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.2.ast %S/Inputs/exprs2.c +// RUN: %clang_cc1 -triple %itanium_abi_triple -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s +// expected-no-diagnostics + diff --git a/clang/test/ASTMerge/function-cpp/Inputs/function-1.cpp b/clang/test/ASTMerge/function-cpp/Inputs/function-1.cpp new file mode 100644 index 0000000..ee97a1a8 --- /dev/null +++ b/clang/test/ASTMerge/function-cpp/Inputs/function-1.cpp @@ -0,0 +1,8 @@ + +template constexpr T add(T arg1, T arg2) { + return arg1 + arg2; +} + +template<> constexpr int add(int arg1, int arg2) { + return arg1 + arg2 + 2; +} diff --git a/clang/test/ASTMerge/function-cpp/test.cpp b/clang/test/ASTMerge/function-cpp/test.cpp new file mode 100644 index 0000000..304ce3c --- /dev/null +++ b/clang/test/ASTMerge/function-cpp/test.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/function-1.cpp +// RUN: %clang_cc1 -std=c++1z -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck %s +// XFAIL: * + +static_assert(add(1, 2) == 5); + +// FIXME: support of templated function overload is still not implemented. +static_assert(add('\1', '\2') == 3); + +// CHECK-NOT: static_assert diff --git a/clang/test/ASTMerge/function/Inputs/function1.c b/clang/test/ASTMerge/function/Inputs/function1.c new file mode 100644 index 0000000..4523bd3 --- /dev/null +++ b/clang/test/ASTMerge/function/Inputs/function1.c @@ -0,0 +1,6 @@ +void f0(int); +void f1(int, float); +void f2(); +void f3(void); +void f4(int, int); +int f5(int) __attribute__((const)); diff --git a/clang/test/ASTMerge/function/Inputs/function2.c b/clang/test/ASTMerge/function/Inputs/function2.c new file mode 100644 index 0000000..6ca810a --- /dev/null +++ b/clang/test/ASTMerge/function/Inputs/function2.c @@ -0,0 +1,7 @@ +typedef int Int; +void f0(Int); +void f1(Int, double); +void f2(int, int); +void f3(int); +static void f4(float, float); +int f5(int) __attribute__((const)); diff --git a/clang/test/ASTMerge/function/test.c b/clang/test/ASTMerge/function/test.c new file mode 100644 index 0000000..8d4d0c1 --- /dev/null +++ b/clang/test/ASTMerge/function/test.c @@ -0,0 +1,17 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/function1.c +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/function2.c +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s + +// CHECK: function2.c:3:6: error: external function 'f1' declared with incompatible types in different translation units ('void (Int, double)' (aka 'void (int, double)') vs. 'void (int, float)') +// CHECK: function1.c:2:6: note: declared here with type 'void (int, float)' +// CHECK: function2.c:5:6: error: external function 'f3' declared with incompatible types in different translation units ('void (int)' vs. 'void (void)') +// CHECK: function1.c:4:6: note: declared here with type 'void (void)' +// CHECK: 2 errors generated + +// expected-error@Inputs/function2.c:3 {{external function 'f1' declared with incompatible types}} +// expected-note@Inputs/function1.c:2 {{declared here}} +// expected-error@Inputs/function2.c:5 {{external function 'f3' declared with incompatible types}} +// expected-note@Inputs/function1.c:4 {{declared here}} diff --git a/clang/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp b/clang/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp new file mode 100644 index 0000000..26fe42e --- /dev/null +++ b/clang/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp @@ -0,0 +1,7 @@ +class A +{ +public: + int x; + A(int _x) : x(_x) { + } +}; diff --git a/clang/test/ASTMerge/inheritance/test.cpp b/clang/test/ASTMerge/inheritance/test.cpp new file mode 100644 index 0000000..7fce82a --- /dev/null +++ b/clang/test/ASTMerge/inheritance/test.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/inheritance-base.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class B : public A { + B(int _a) : A(_a) { + } +}; diff --git a/clang/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp b/clang/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp new file mode 100644 index 0000000..fd51f86 --- /dev/null +++ b/clang/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp @@ -0,0 +1,19 @@ +class A_base +{ +public: + int x; + A_base() : x(0) { + } + A_base(int _x) : x(static_cast(_x)) { + } +}; + +class A : public A_base +{ +public: + int y; + struct { int z; }; + int array[2]; + A(int _x) : A_base(_x), y(0), z(1), array{{2},{3}} { + } +}; diff --git a/clang/test/ASTMerge/init-ctors/test.cpp b/clang/test/ASTMerge/init-ctors/test.cpp new file mode 100644 index 0000000..5f0ba4d --- /dev/null +++ b/clang/test/ASTMerge/init-ctors/test.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/init-ctors-classes.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class B { + int method_1() { + A a(0); + return a.x; + } +}; diff --git a/clang/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp b/clang/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp new file mode 100644 index 0000000..f6f7697 --- /dev/null +++ b/clang/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp @@ -0,0 +1,2 @@ +template +class C { static X x; }; diff --git a/clang/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp b/clang/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp new file mode 100644 index 0000000..7cf5fc2 --- /dev/null +++ b/clang/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp @@ -0,0 +1,2 @@ +template +X C::x; diff --git a/clang/test/ASTMerge/injected-class-name-decl/test.cpp b/clang/test/ASTMerge/injected-class-name-decl/test.cpp new file mode 100644 index 0000000..9f31674 --- /dev/null +++ b/clang/test/ASTMerge/injected-class-name-decl/test.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.ast %S/Inputs/inject1.cpp +// RUN: %clang_cc1 -std=c++1z -emit-obj -o /dev/null -ast-merge %t.ast %S/Inputs/inject2.cpp +// expected-no-diagnostics diff --git a/clang/test/ASTMerge/interface/Inputs/interface1.m b/clang/test/ASTMerge/interface/Inputs/interface1.m new file mode 100644 index 0000000..6192150 --- /dev/null +++ b/clang/test/ASTMerge/interface/Inputs/interface1.m @@ -0,0 +1,105 @@ +// Matches +@interface I1 { + int ivar1; +} +@end + +// Matches +@interface I2 : I1 { + float ivar2; +} +@end + +// Ivar mismatch +@interface I3 { + int ivar1; + int ivar2; +} +@end + +// Superclass mismatch +@interface I4 : I2 { +} +@end + +// Methods match +@interface I5 +- (int)foo; ++ (float)bar; +@end + +// Method mismatch +@interface I6 +- (int)foo; ++ (int)foo; +@end + +// Method mismatch +@interface I7 +- (int)foo; ++ (int)bar:(int)x; +@end + +// Method mismatch +@interface I8 +- (int)foo; ++ (int)bar:(float)x; +@end + +// Matching protocol +@protocol P0 ++ (int)foo; +- (int)bar:(float)x; +@end + +// Protocol with mismatching method +@protocol P1 ++ (int)foo; +- (int)bar:(float)x; +@end + +// Interface with protocol +@interface I9 ++ (int)foo; +- (int)bar:(float)x; +@end + +// Protocol with protocol +@protocol P2 +- (float)wibble:(int)a1 second:(int)a2; +@end + +// Forward-declared interfaces +@class I10, I11; +@interface I12 +@end + +// Forward-declared protocols +@protocol P3, P5; +@protocol P4 +- (double)honk:(int)a; +@end + +// Interface with implementation +@interface I13 +@end + +@implementation I13 +@end + +@interface I13a +@end + +@implementation I13a +@end + +// Implementation by itself +@implementation I14 : I12 +@end + +@implementation I15 : I12 +@end + +@interface ImportSelectorSLoc { } +-(int)addInt:(int)a toInt:(int)b moduloInt:(int)c; // don't crash here +@end diff --git a/clang/test/ASTMerge/interface/Inputs/interface2.m b/clang/test/ASTMerge/interface/Inputs/interface2.m new file mode 100644 index 0000000..2133bd1 --- /dev/null +++ b/clang/test/ASTMerge/interface/Inputs/interface2.m @@ -0,0 +1,100 @@ +// Matches +@interface I1 { + int ivar1; +} +@end + +// Matches +@interface I2 : I1 { + float ivar2; +} +@end + +// Ivar mismatch +@interface I3 { + int ivar1; + float ivar2; +} +@end + +// Superclass mismatch +@interface I4 : I1 { +} +@end + +// Methods match +@interface I5 ++ (float)bar; +- (int)foo; +@end + +// Method mismatch +@interface I6 ++ (float)foo; +@end + +// Method mismatch +@interface I7 +- (int)foo; ++ (int)bar:(float)x; +@end + +// Method mismatch +@interface I8 +- (int)foo; ++ (int)bar:(float)x, ...; +@end + +// Matching protocol +@protocol P0 ++ (int)foo; +- (int)bar:(float)x; +@end + +// Protocol with mismatching method +@protocol P1 ++ (int)foo; +- (int)bar:(double)x; +@end + +// Interface with protocol +@interface I9 ++ (int)foo; +- (int)bar:(float)x; +@end + +// Protocol with protocol +@protocol P2 +- (float)wibble:(int)a1 second:(int)a2; +@end + +// Forward-declared interface +@class I10; @interface I12 @end +@interface I11 +@end + +// Forward-declared protocols +@protocol P3, P4; +@protocol P5 +- (double)honk:(int)a; +@end + +// Interface with implementation +@interface I13 +@end + +@implementation I13 +@end + +@interface I13b +@end + +@implementation I13b +@end + +// Implementation by itself +@implementation I14 : I12 +@end + +@implementation I15 : I11 +@end diff --git a/clang/test/ASTMerge/interface/test.m b/clang/test/ASTMerge/interface/test.m new file mode 100644 index 0000000..7338e90 --- /dev/null +++ b/clang/test/ASTMerge/interface/test.m @@ -0,0 +1,24 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/interface1.m +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/interface2.m +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: interface2.m:16:9: error: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int') +// CHECK: interface1.m:16:7: note: declared here with type 'int' +// CHECK: interface1.m:21:12: error: class 'I4' has incompatible superclasses +// CHECK: interface1.m:21:17: note: inherits from superclass 'I2' here +// CHECK: interface2.m:21:17: note: inherits from superclass 'I1' here +// CHECK: interface2.m:33:1: error: class method 'foo' has incompatible result types in different translation units ('float' vs. 'int') +// CHECK: interface1.m:34:1: note: class method 'foo' also declared here +// CHECK: interface2.m:39:19: error: class method 'bar:' has a parameter with a different types in different translation units ('float' vs. 'int') +// CHECK: interface1.m:40:17: note: declared here with type 'int' +// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another +// CHECK: interface1.m:46:1: note: class method 'bar:' also declared here +// CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float') +// CHECK: interface1.m:58:19: note: declared here with type 'float' +// CHECK: interface1.m:100:17: error: class 'I15' has incompatible superclasses +// CHECK: interface1.m:100:17: note: inherits from superclass 'I12' here +// CHECK: interface2.m:99:17: note: inherits from superclass 'I11' here +// CHECK: 8 errors generated + diff --git a/clang/test/ASTMerge/macro/Inputs/macro.modulemap b/clang/test/ASTMerge/macro/Inputs/macro.modulemap new file mode 100644 index 0000000..dba1f22 --- /dev/null +++ b/clang/test/ASTMerge/macro/Inputs/macro.modulemap @@ -0,0 +1,4 @@ +module macro1 [extern_c] { + header "macro1.h" + export * +} diff --git a/clang/test/ASTMerge/macro/Inputs/macro1.h b/clang/test/ASTMerge/macro/Inputs/macro1.h new file mode 100644 index 0000000..9613394 --- /dev/null +++ b/clang/test/ASTMerge/macro/Inputs/macro1.h @@ -0,0 +1,5 @@ +typedef void *VoidRef; + +void maybeNull( + int i, + _Nullable VoidRef *_Nullable); diff --git a/clang/test/ASTMerge/macro/Inputs/macro1.m b/clang/test/ASTMerge/macro/Inputs/macro1.m new file mode 100644 index 0000000..2612613 --- /dev/null +++ b/clang/test/ASTMerge/macro/Inputs/macro1.m @@ -0,0 +1,5 @@ +@import macro1; + +void foo() { + maybeNull(0, 0); +} diff --git a/clang/test/ASTMerge/macro/Inputs/macro2.m b/clang/test/ASTMerge/macro/Inputs/macro2.m new file mode 100644 index 0000000..b5b155a --- /dev/null +++ b/clang/test/ASTMerge/macro/Inputs/macro2.m @@ -0,0 +1,5 @@ +void foo(); + +void bar() { + foo(); +} diff --git a/clang/test/ASTMerge/macro/test.m b/clang/test/ASTMerge/macro/test.m new file mode 100644 index 0000000..77e596d --- /dev/null +++ b/clang/test/ASTMerge/macro/test.m @@ -0,0 +1,6 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t/cache +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.1.ast %S/Inputs/macro1.m +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.2.ast %S/Inputs/macro2.m +// RUN: %clang_cc1 -fmodules -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s +// expected-no-diagnostics diff --git a/clang/test/ASTMerge/namespace/Inputs/namespace1.cpp b/clang/test/ASTMerge/namespace/Inputs/namespace1.cpp new file mode 100644 index 0000000..4a53952 --- /dev/null +++ b/clang/test/ASTMerge/namespace/Inputs/namespace1.cpp @@ -0,0 +1,27 @@ +// Merge success +namespace N1 { + int x; +} + +// Merge multiple namespaces +namespace N2 { + extern int x; +} +namespace N2 { + extern float y; +} + +// Merge namespace with conflict +namespace N3 { + extern float z; +} + +namespace AliasWithSameName = N3; + +namespace TestUnresolvedTypenameAndValueDecls { +template class Base { +public: + typedef T foo; + void bar(); +}; +} diff --git a/clang/test/ASTMerge/namespace/Inputs/namespace2.cpp b/clang/test/ASTMerge/namespace/Inputs/namespace2.cpp new file mode 100644 index 0000000..f65057d --- /dev/null +++ b/clang/test/ASTMerge/namespace/Inputs/namespace2.cpp @@ -0,0 +1,60 @@ +// Merge success +namespace N1 { + extern int x0; +} + +// Merge multiple namespaces +namespace N2 { + extern int x; +} +namespace N2 { + extern float y; +} + +// Merge namespace with conflict +namespace N3 { + extern double z; +} + +namespace Enclosing { +namespace Nested { + const int z = 4; +} +} + +namespace ContainsInline { + inline namespace Inline { + const int z = 10; + } +} + +namespace TestAliasName = Enclosing::Nested; +// NOTE: There is no warning on this alias. +namespace AliasWithSameName = Enclosing::Nested; + +namespace TestUsingDecls { + +namespace A { +void foo(); +} +namespace B { +using A::foo; // <- a UsingDecl creating a UsingShadow +} + +}// end namespace TestUsingDecls + +namespace TestUnresolvedTypenameAndValueDecls { + +template class Base; +template class Derived : public Base { +public: + using typename Base::foo; + using Base::bar; + typedef typename Derived::foo NewUnresolvedUsingType; +}; + +} // end namespace TestUnresolvedTypenameAndValueDecls + +namespace TestUsingNamespace { + using namespace Enclosing; +} diff --git a/clang/test/ASTMerge/namespace/test.cpp b/clang/test/ASTMerge/namespace/test.cpp new file mode 100644 index 0000000..f0f8b73 --- /dev/null +++ b/clang/test/ASTMerge/namespace/test.cpp @@ -0,0 +1,19 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/namespace1.cpp +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/namespace2.cpp +// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +static_assert(TestAliasName::z == 4); +static_assert(ContainsInline::z == 10); + +void testImport() { + typedef TestUnresolvedTypenameAndValueDecls::Derived Imported; + Imported a; // Successful instantiation + static_assert(sizeof(Imported::foo) == sizeof(int)); + static_assert(sizeof(TestUnresolvedTypenameAndValueDecls::Derived::NewUnresolvedUsingType) == sizeof(double)); +} + + +// CHECK: namespace2.cpp:16:17: error: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float') +// CHECK: namespace1.cpp:16:16: note: declared here with type 'float' diff --git a/clang/test/ASTMerge/property/Inputs/property1.m b/clang/test/ASTMerge/property/Inputs/property1.m new file mode 100644 index 0000000..22fe0a0 --- /dev/null +++ b/clang/test/ASTMerge/property/Inputs/property1.m @@ -0,0 +1,31 @@ +// Matching properties +@interface I1 { +} +- (int)getProp2; +- (void)setProp2:(int)value; +@end + +// Mismatched property +@interface I2 +@property (readonly) float Prop1; +@end + +// Properties with implementations +@interface I3 { + int ivar1; + int ivar2; + int ivar3; + int Prop4; +} +@property int Prop1; +@property int Prop2; +@property int Prop3; +@property int Prop4; +@end + +@implementation I3 +@synthesize Prop1 = ivar1; +@synthesize Prop2 = ivar3; +@dynamic Prop3; +@synthesize Prop4; +@end diff --git a/clang/test/ASTMerge/property/Inputs/property2.m b/clang/test/ASTMerge/property/Inputs/property2.m new file mode 100644 index 0000000..64a03fb --- /dev/null +++ b/clang/test/ASTMerge/property/Inputs/property2.m @@ -0,0 +1,33 @@ +// Matching properties +@interface I1 { +} +- (int)getProp2; +- (void)setProp2:(int)value; +@property (readonly) int Prop1; +@property (getter = getProp2, setter = setProp2:) int Prop2; +@end + +// Mismatched property +@interface I2 +@property (readonly) int Prop1; +@end + +// Properties with implementations +@interface I3 { + int ivar1; + int ivar2; + int ivar3; + int Prop4; +} +@property int Prop1; +@property int Prop2; +@property int Prop3; +@property int Prop4; +@end + +@implementation I3 +@synthesize Prop2 = ivar2; +@synthesize Prop1 = ivar1; +@synthesize Prop3 = ivar3; +@synthesize Prop4 = Prop4; +@end diff --git a/clang/test/ASTMerge/property/test.m b/clang/test/ASTMerge/property/test.m new file mode 100644 index 0000000..e48d54e --- /dev/null +++ b/clang/test/ASTMerge/property/test.m @@ -0,0 +1,15 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/property1.m +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/property2.m +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: property2.m:12:26: error: property 'Prop1' declared with incompatible types in different translation units ('int' vs. 'float') +// CHECK: property1.m:10:28: note: declared here with type 'float' +// CHECK: property2.m:12:26: error: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float') +// CHECK: property1.m:10:28: note: instance method 'Prop1' also declared here +// CHECK: property1.m:28:21: error: property 'Prop2' is synthesized to different ivars in different translation units ('ivar3' vs. 'ivar2') +// CHECK: property2.m:29:21: note: property is synthesized to ivar 'ivar2' here +// CHECK: property1.m:29:10: error: property 'Prop3' is implemented with @dynamic in one translation but @synthesize in another translation unit +// CHECK: property2.m:31:13: note: property 'Prop3' is implemented with @synthesize here +// CHECK: 4 errors generated. diff --git a/clang/test/ASTMerge/std-initializer-list/Inputs/il.cpp b/clang/test/ASTMerge/std-initializer-list/Inputs/il.cpp new file mode 100644 index 0000000..3b2ac18 --- /dev/null +++ b/clang/test/ASTMerge/std-initializer-list/Inputs/il.cpp @@ -0,0 +1,9 @@ +namespace std { +template +struct initializer_list { + const T *begin, *end; + initializer_list(); +}; +} // namespace std + +std::initializer_list IL = {1, 2, 3, 4}; diff --git a/clang/test/ASTMerge/std-initializer-list/test.cpp b/clang/test/ASTMerge/std-initializer-list/test.cpp new file mode 100644 index 0000000..ca7330d --- /dev/null +++ b/clang/test/ASTMerge/std-initializer-list/test.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp +// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +// CHECK-NOT: unsupported AST node diff --git a/clang/test/ASTMerge/struct/Inputs/struct1.c b/clang/test/ASTMerge/struct/Inputs/struct1.c new file mode 100644 index 0000000..a85aec7 --- /dev/null +++ b/clang/test/ASTMerge/struct/Inputs/struct1.c @@ -0,0 +1,141 @@ +typedef int Int; +typedef float Float; + +// Matches +struct S0 { + Int field1; + Float field2; +}; + +struct S0 x0; + +// Mismatch in field type +struct S1 { + Int field1; + int field2; +}; + +struct S1 x1; + +// Mismatch in tag kind. +struct S2 { int i; float f; } x2; + +// Missing fields +struct S3 { int i; float f; double d; } x3; + +// Extra fields +struct S4 { int i; } x4; + +// Bit-field matches +struct S5 { int i : 8; unsigned j : 8; } x5; + +// Bit-field mismatch +struct S6 { int i : 8; unsigned j : 8; } x6; + +// Bit-field mismatch +struct S7 { int i : 8; unsigned j : 8; } x7; + +// Incomplete type +struct S8 *x8; + +// Incomplete type +struct S9 { int i; float f; } *x9; + +// Incomplete type +struct S10 *x10; + +// Matches +struct ListNode { + int value; + struct ListNode *Next; +} xList; + +// Mismatch due to struct used internally +struct DeepError { + int value; + struct DeeperError { int i; int f; } *Deeper; +} xDeep; + +// Matches +struct { + Int i; + float f; +} x11; + +// Matches +typedef struct { + Int i; + float f; +} S12; + +S12 x12; + +// Mismatch +typedef struct { + Float i; // Mismatch here. + float f; +} S13; + +S13 x13; + +// Matches +struct Unnamed { + union { + struct { + int i; + } S; + struct { + float i; + } R; + } U; +} x14; + +// Matches +struct DeepUnnamed { + union { + union { + struct { + long i; + } S; + struct { + int i; + } R; + } U1; + union { + struct { + long i; + } S; + struct { + float i; + } T; + } U2; + } U; + struct { + long i; + } V; +} x15; + +// Mismatch due to unnamed struct used internally +struct DeepUnnamedError { + union { + union { + struct { + long i; + } S; + struct { + int i; + } R; + } U1; + union { + struct { + long i; // Mismatch here. + } S; + struct { + float i; + } T; + } U2; + } U; + struct { + long i; + } V; +} x16; diff --git a/clang/test/ASTMerge/struct/Inputs/struct2.c b/clang/test/ASTMerge/struct/Inputs/struct2.c new file mode 100644 index 0000000..49fe36d --- /dev/null +++ b/clang/test/ASTMerge/struct/Inputs/struct2.c @@ -0,0 +1,138 @@ +// Matches +struct S0 { + int field1; + float field2; +}; + +struct S0 x0; + +// Mismatch in field type +struct S1 { + int field1; + float field2; +}; + +struct S1 x1; + +// Mismatch in tag kind. +union S2 { int i; float f; } x2; + +// Missing fields +struct S3 { int i; float f; } x3; + +// Extra fields +struct S4 { int i; float f; } x4; + +// Bit-field matches +struct S5 { int i : 8; unsigned j : 8; } x5; + +// Bit-field mismatch +struct S6 { int i : 8; unsigned j; } x6; + +// Bit-field mismatch +struct S7 { int i : 8; unsigned j : 16; } x7; + +// Incomplete type +struct S8 { int i; float f; } *x8; + +// Incomplete type +struct S9 *x9; + +// Incomplete type +struct S10 *x10; + +// Matches +struct ListNode { + int value; + struct ListNode *Next; +} xList; + +// Mismatch due to struct used internally +struct DeepError { + int value; + struct DeeperError { int i; float f; } *Deeper; +} xDeep; + +// Matches +struct { + int i; + float f; +} x11; + +// Matches +typedef struct { + int i; + float f; +} S12; + +S12 x12; + +// Mismatch +typedef struct { + int i; // Mismatch here. + float f; +} S13; + +S13 x13; + +// Matches +struct Unnamed { + union { + struct { + int i; + } S; + struct { + float i; + } R; + } U; +} x14; + +// Matches +struct DeepUnnamed { + union { + union { + struct { + long i; + } S; + struct { + int i; + } R; + } U1; + union { + struct { + long i; + } S; + struct { + float i; + } T; + } U2; + } U; + struct { + long i; + } V; +} x15; + +// Mismatch due to unnamed struct used internally +struct DeepUnnamedError { + union { + union { + struct { + long i; + } S; + struct { + int i; + } R; + } U1; + union { + struct { + float i; // Mismatch here. + } S; + struct { + float i; + } T; + } U2; + } U; + struct { + long i; + } V; +} x16; diff --git a/clang/test/ASTMerge/struct/test.c b/clang/test/ASTMerge/struct/test.c new file mode 100644 index 0000000..1f5f66d --- /dev/null +++ b/clang/test/ASTMerge/struct/test.c @@ -0,0 +1,57 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/struct1.c +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/struct2.c +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: struct1.c:13:8: warning: type 'struct S1' has incompatible definitions in different translation units +// CHECK: struct1.c:15:7: note: field 'field2' has type 'int' here +// CHECK: struct2.c:12:9: note: field 'field2' has type 'float' here +// CHECK: struct2.c:15:11: error: external variable 'x1' declared with incompatible types in different translation units ('struct S1' vs. 'struct S1') +// CHECK: struct1.c:18:11: note: declared here with type 'struct S1' +// CHECK: struct1.c:21:8: warning: type 'struct S2' has incompatible definitions in different translation units +// CHECK: struct2.c:18:7: note: 'S2' is a union here +// CHECK: struct2.c:18:30: error: external variable 'x2' declared with incompatible types in different translation units ('union S2' vs. 'struct S2') +// CHECK: struct1.c:21:31: note: declared here with type 'struct S2' +// CHECK: struct1.c:24:8: warning: type 'struct S3' has incompatible definitions in different translation units +// CHECK: struct1.c:24:36: note: field 'd' has type 'double' here +// CHECK: struct2.c:21:8: note: no corresponding field here +// CHECK: struct2.c:21:31: error: external variable 'x3' declared with incompatible types in different translation units ('struct S3' vs. 'struct S3') +// CHECK: struct1.c:24:41: note: declared here with type 'struct S3' +// CHECK: struct1.c:27:8: warning: type 'struct S4' has incompatible definitions in different translation units +// CHECK: struct2.c:24:26: note: field 'f' has type 'float' here +// CHECK: struct1.c:27:8: note: no corresponding field here +// CHECK: struct2.c:24:31: error: external variable 'x4' declared with incompatible types in different translation units ('struct S4' vs. 'struct S4') +// CHECK: struct1.c:27:22: note: declared here with type 'struct S4' +// CHECK: struct1.c:33:8: warning: type 'struct S6' has incompatible definitions in different translation units +// CHECK: struct1.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 8 here +// CHECK: struct2.c:30:33: note: field 'j' is not a bit-field +// CHECK: struct2.c:30:38: error: external variable 'x6' declared with incompatible types in different translation units ('struct S6' vs. 'struct S6') +// CHECK: struct1.c:33:42: note: declared here with type 'struct S6' +// CHECK: struct1.c:36:8: warning: type 'struct S7' has incompatible definitions in different translation units +// CHECK: struct1.c:36:33: note: bit-field 'j' with type 'unsigned int' and length 8 here +// CHECK: struct2.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 16 here +// CHECK: struct2.c:33:43: error: external variable 'x7' declared with incompatible types in different translation units ('struct S7' vs. 'struct S7') +// CHECK: struct1.c:36:42: note: declared here with type 'struct S7' +// CHECK: struct1.c:56:10: warning: type 'struct DeeperError' has incompatible definitions in different translation units +// CHECK: struct1.c:56:35: note: field 'f' has type 'int' here +// CHECK: struct2.c:53:37: note: field 'f' has type 'float' here +// CHECK: struct1.c:54:8: warning: type 'struct DeepError' has incompatible definitions in different translation units +// CHECK: struct1.c:56:41: note: field 'Deeper' has type 'struct DeeperError *' here +// CHECK: struct2.c:53:43: note: field 'Deeper' has type 'struct DeeperError *' here +// CHECK: struct2.c:54:3: error: external variable 'xDeep' declared with incompatible types in different translation units ('struct DeepError' vs. 'struct DeepError') +// CHECK: struct1.c:57:3: note: declared here with type 'struct DeepError' +// CHECK: struct1.c:74:9: warning: type 'S13' has incompatible definitions in different translation units +// CHECK: struct1.c:75:9: note: field 'i' has type 'Float' (aka 'float') here +// CHECK: struct2.c:72:7: note: field 'i' has type 'int' here +// CHECK: struct2.c:76:5: error: external variable 'x13' declared with incompatible types in different translation units ('S13' vs. 'S13') +// CHECK: struct1.c:79:5: note: declared here with type 'S13' +// CHECK: struct1.c:130:7: warning: type 'struct DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS:.+]]struct1.c:130:7)' has incompatible definitions in different translation units +// CHECK: struct1.c:131:14: note: field 'i' has type 'long' here +// CHECK: struct2.c:128:15: note: field 'i' has type 'float' here +// CHECK: struct1.c:129:5: warning: type 'union DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS]]struct1.c:129:5)' has incompatible definitions in different translation units +// CHECK: struct1.c:132:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct1.c:130:7)' here +// CHECK: struct2.c:129:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct2.c:127:7)' here +// CHECK: struct2.c:138:3: error: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError') +// CHECK: struct1.c:141:3: note: declared here with type 'struct DeepUnnamedError' +// CHECK: 11 warnings and 9 errors generated diff --git a/clang/test/ASTMerge/typedef/Inputs/typedef1.c b/clang/test/ASTMerge/typedef/Inputs/typedef1.c new file mode 100644 index 0000000..5657675 --- /dev/null +++ b/clang/test/ASTMerge/typedef/Inputs/typedef1.c @@ -0,0 +1,4 @@ +typedef int Typedef1; +typedef int Typedef2; +Typedef1 x1; +Typedef2 x2; diff --git a/clang/test/ASTMerge/typedef/Inputs/typedef2.c b/clang/test/ASTMerge/typedef/Inputs/typedef2.c new file mode 100644 index 0000000..129d710 --- /dev/null +++ b/clang/test/ASTMerge/typedef/Inputs/typedef2.c @@ -0,0 +1,4 @@ +typedef int Typedef1; +typedef double Typedef2; +Typedef1 x1; +Typedef2 x2; diff --git a/clang/test/ASTMerge/typedef/test.c b/clang/test/ASTMerge/typedef/test.c new file mode 100644 index 0000000..ec8355d --- /dev/null +++ b/clang/test/ASTMerge/typedef/test.c @@ -0,0 +1,9 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/typedef1.c +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/typedef2.c +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: typedef2.c:4:10: error: external variable 'x2' declared with incompatible types in different translation units ('Typedef2' (aka 'double') vs. 'Typedef2' (aka 'int')) +// CHECK: typedef1.c:4:10: note: declared here with type 'Typedef2' (aka 'int') +// CHECK: 1 error diff --git a/clang/test/ASTMerge/unnamed_fields/Inputs/il.cpp b/clang/test/ASTMerge/unnamed_fields/Inputs/il.cpp new file mode 100644 index 0000000..1bb0f35 --- /dev/null +++ b/clang/test/ASTMerge/unnamed_fields/Inputs/il.cpp @@ -0,0 +1,3 @@ +void f(int X, int Y, bool Z) { + auto x = [X, Y, Z] { (void)Z; }; +} diff --git a/clang/test/ASTMerge/unnamed_fields/test.cpp b/clang/test/ASTMerge/unnamed_fields/test.cpp new file mode 100644 index 0000000..6ae3176 --- /dev/null +++ b/clang/test/ASTMerge/unnamed_fields/test.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp +// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +// CHECK-NOT: warning: field '' declared with incompatible types in different translation units ('bool' vs. 'int') diff --git a/clang/test/ASTMerge/var-cpp/Inputs/var1.cpp b/clang/test/ASTMerge/var-cpp/Inputs/var1.cpp new file mode 100644 index 0000000..e29db9d --- /dev/null +++ b/clang/test/ASTMerge/var-cpp/Inputs/var1.cpp @@ -0,0 +1,17 @@ + +template +constexpr T my_pi = T(3.1415926535897932385L); // variable template + +template <> constexpr char my_pi = '3'; // variable template specialization + +template +struct Wrapper { + template static constexpr U my_const = U(1); + // Variable template partial specialization with member variable. + template static constexpr U *my_const = (U *)(0); +}; + +constexpr char a[] = "hello"; + +template <> template <> +constexpr const char *Wrapper::my_const = a; diff --git a/clang/test/ASTMerge/var-cpp/test.cpp b/clang/test/ASTMerge/var-cpp/test.cpp new file mode 100644 index 0000000..28d38d58 --- /dev/null +++ b/clang/test/ASTMerge/var-cpp/test.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-pch -std=c++17 -o %t.1.ast %S/Inputs/var1.cpp +// RUN: %clang_cc1 -std=c++17 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 + +static_assert(my_pi == (double)3.1415926535897932385L); +static_assert(my_pi == '3'); + +static_assert(Wrapper::my_const == 1.f); +static_assert(Wrapper::my_const == nullptr); +static_assert(Wrapper::my_const == a); diff --git a/clang/test/ASTMerge/var/Inputs/var1.c b/clang/test/ASTMerge/var/Inputs/var1.c new file mode 100644 index 0000000..4f5cbe1 --- /dev/null +++ b/clang/test/ASTMerge/var/Inputs/var1.c @@ -0,0 +1,7 @@ +int *x0; +float **x1; +#include "var1.h" +int xarray0[17]; +int xarray1[]; +int xarray2[18]; +int xarray3[18]; diff --git a/clang/test/ASTMerge/var/Inputs/var1.h b/clang/test/ASTMerge/var/Inputs/var1.h new file mode 100644 index 0000000..1518e17 --- /dev/null +++ b/clang/test/ASTMerge/var/Inputs/var1.h @@ -0,0 +1 @@ +double x2; diff --git a/clang/test/ASTMerge/var/Inputs/var2.c b/clang/test/ASTMerge/var/Inputs/var2.c new file mode 100644 index 0000000..01986e4 --- /dev/null +++ b/clang/test/ASTMerge/var/Inputs/var2.c @@ -0,0 +1,7 @@ +int *x0; +double *x1; +int x2; +int xarray0[17]; +int xarray1[17]; +int xarray2[]; +int xarray3[17]; diff --git a/clang/test/ASTMerge/var/test.c b/clang/test/ASTMerge/var/test.c new file mode 100644 index 0000000..f0a3d92 --- /dev/null +++ b/clang/test/ASTMerge/var/test.c @@ -0,0 +1,14 @@ +// FIXME: Errors are now warnings. +// XFAIL: * +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/var1.c +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/var2.c +// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -fdiagnostics-show-note-include-stack %s 2>&1 | FileCheck %s + +// CHECK: var2.c:2:9: error: external variable 'x1' declared with incompatible types in different translation units ('double *' vs. 'float **') +// CHECK: var1.c:2:9: note: declared here with type 'float **' +// CHECK: var2.c:3:5: error: external variable 'x2' declared with incompatible types in different translation units ('int' vs. 'double') +// CHECK: In file included from{{.*}}var1.c:3: +// CHECK: var1.h:1:8: note: declared here with type 'double' +// CHECK: error: external variable 'xarray3' declared with incompatible types in different translation units ('int [17]' vs. 'int [18]') +// CHECK: var1.c:7:5: note: declared here with type 'int [18]' +// CHECK: 3 errors -- 2.7.4