165 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
 | 
						|
// RUN: clang-modernize -use-nullptr %t.cpp -- -I %S
 | 
						|
// RUN: FileCheck -input-file=%t.cpp %s
 | 
						|
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t2.cpp
 | 
						|
// RUN: clang-modernize -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);
 | 
						|
 | 
						|
#define OPTIONAL_CODE(...) __VA_ARGS__
 | 
						|
#define NOT_NULL dummy(0)
 | 
						|
#define CALL(X) X
 | 
						|
  OPTIONAL_CODE(NOT_NULL);
 | 
						|
  // CHECK: OPTIONAL_CODE(NOT_NULL);
 | 
						|
  CALL(NOT_NULL);
 | 
						|
  // CHECK: CALL(NOT_NULL);
 | 
						|
}
 |