blob: de0996ad0ae1ced60e197453452cd3d196256d13 [file] [log] [blame]
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: cpp11-migrate -use-nullptr %t.cpp -- -I %S
// RUN: FileCheck -input-file=%t.cpp %s
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t2.cpp
// RUN: cpp11-migrate -use-nullptr -user-null-macros=MY_NULL %t2.cpp -- -I %S
// RUN: FileCheck -check-prefix=USER-SUPPLIED-NULL -input-file=%t2.cpp %s
#define NULL 0
// CHECK: #define NULL 0
void dummy(int*) {}
void side_effect() {}
#define MACRO_EXPANSION_HAS_NULL \
void foo() { \
dummy(0); \
dummy(NULL); \
side_effect(); \
}
// CHECK: void foo() { \
// CHECK-NEXT: dummy(0); \
// CHECK-NEXT: dummy(NULL); \
MACRO_EXPANSION_HAS_NULL;
// CHECK: MACRO_EXPANSION_HAS_NULL;
#undef MACRO_EXPANSION_HAS_NULL
void test_macro_expansion1() {
#define MACRO_EXPANSION_HAS_NULL \
dummy(NULL); \
side_effect();
// CHECK: dummy(NULL); \
// CHECK-NEXT: side_effect();
MACRO_EXPANSION_HAS_NULL;
// CHECK: MACRO_EXPANSION_HAS_NULL;
#undef MACRO_EXPANSION_HAS_NULL
}
// Test macro expansion with cast sequence, PR15572
void test_macro_expansion2() {
#define MACRO_EXPANSION_HAS_NULL \
dummy((int*)0); \
side_effect();
// CHECK: dummy((int*)0); \
// CHECK-NEXT: side_effect();
MACRO_EXPANSION_HAS_NULL;
// CHECK: MACRO_EXPANSION_HAS_NULL;
#undef MACRO_EXPANSION_HAS_NULL
}
void test_macro_expansion3() {
#define MACRO_EXPANSION_HAS_NULL \
dummy(NULL); \
side_effect();
// CHECK: dummy(NULL); \
// CHECK-NEXT: side_effect();
#define OUTER_MACRO \
MACRO_EXPANSION_HAS_NULL; \
side_effect();
OUTER_MACRO;
// CHECK: OUTER_MACRO;
#undef OUTER_MACRO
#undef MACRO_EXPANSION_HAS_NULL
}
void test_macro_expansion4() {
#define MY_NULL NULL
int *p = MY_NULL;
// CHECK: int *p = MY_NULL;
// USER-SUPPLIED-NULL: int *p = nullptr;
#undef MY_NULL
}
#define IS_EQ(x, y) if (x != y) return;
void test_macro_args() {
int i = 0;
int *Ptr;
IS_EQ(static_cast<int*>(0), Ptr);
// CHECK: IS_EQ(static_cast<int*>(nullptr), Ptr);
IS_EQ(0, Ptr); // literal
// CHECK: IS_EQ(nullptr, Ptr);
IS_EQ(NULL, Ptr); // macro
// CHECK: IS_EQ(nullptr, Ptr);
// These are ok since the null literal is not spelled within a macro.
#define myassert(x) if (!(x)) return;
myassert(0 == Ptr);
// CHECK: myassert(nullptr == Ptr);
myassert(NULL == Ptr);
// CHECK: myassert(nullptr == Ptr);
// These are bad as the null literal is buried in a macro.
#define BLAH(X) myassert(0 == (X));
// CHECK: #define BLAH(X) myassert(0 == (X));
#define BLAH2(X) myassert(NULL == (X));
// CHECK: #define BLAH2(X) myassert(NULL == (X));
BLAH(Ptr);
// CHECK: BLAH(Ptr);
BLAH2(Ptr);
// CHECK: BLAH2(Ptr);
// Same as above but testing extra macro expansion.
#define EXPECT_NULL(X) IS_EQ(0, X);
// CHECK: #define EXPECT_NULL(X) IS_EQ(0, X);
#define EXPECT_NULL2(X) IS_EQ(NULL, X);
// CHECK: #define EXPECT_NULL2(X) IS_EQ(NULL, X);
EXPECT_NULL(Ptr);
// CHECK: EXPECT_NULL(Ptr);
EXPECT_NULL2(Ptr);
// CHECK: EXPECT_NULL2(Ptr);
// Almost the same as above but now null literal is not in a macro so ok
// to transform.
#define EQUALS_PTR(X) IS_EQ(X, Ptr);
EQUALS_PTR(0);
EQUALS_PTR(NULL);
// Same as above but testing extra macro expansion.
#define EQUALS_PTR_I(X) EQUALS_PTR(X)
EQUALS_PTR_I(0);
// CHECK: EQUALS_PTR_I(nullptr);
EQUALS_PTR_I(NULL);
// CHECK: EQUALS_PTR_I(nullptr);
// Ok since null literal not within macro. However, now testing macro
// used as arg to another macro.
#define decorate(EXPR) side_effect(); EXPR;
decorate(IS_EQ(NULL, Ptr));
// CHECK: decorate(IS_EQ(nullptr, Ptr));
decorate(IS_EQ(0, Ptr));
// CHECK: decorate(IS_EQ(nullptr, Ptr));
// This macro causes a NullToPointer cast to happen where 0 is assigned to z
// but the 0 literal cannot be replaced because it is also used as an
// integer in the comparison.
#define INT_AND_PTR_USE(X) do { int *z = X; if (X == 4) break; } while(false)
INT_AND_PTR_USE(0);
// CHECK: INT_AND_PTR_USE(0);
// Both uses of X in this case result in NullToPointer casts so replacement
// is possible.
#define PTR_AND_PTR_USE(X) do { int *z = X; if (X != z) break; } while(false)
PTR_AND_PTR_USE(0);
// CHECK: PTR_AND_PTR_USE(nullptr);
PTR_AND_PTR_USE(NULL);
// CHECK: PTR_AND_PTR_USE(nullptr);
}