Skip to content

Commit 925f74c

Browse files
committed
[Clang] Add -fwrapv-pointer flag
GCC supports three flags related to overflow behavior: * `-fwrapv`: Makes signed integer overflow well-defined. * `-fwrapv-pointer`: Makes pointer overflow well-defined. * `-fno-strict-overflow`: Implies `-fwrapv -fwrapv-pointer`, making both signed integer overflow and pointer overflow well-defined. Clang currently only supports `-fno-strict-overflow` and `-fwrapv`, but not `-fwrapv-pointer`. This PR proposes to introduce `-fwrapv-pointer` and adjust the semantics of `-fwrapv` to match GCC. This allows signed integer overflow and pointer overflow to be controlled independently, while `-fno-strict-overflow` still exists to control both at the same time (and that option is consistent across GCC and Clang).
1 parent ff0f1dd commit 925f74c

14 files changed

+88
-40
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,15 @@ code bases.
7979
Undefined behavior due to pointer addition overflow can be reliably detected
8080
using ``-fsanitize=pointer-overflow``. It is also possible to use
8181
``-fno-strict-overflow`` to opt-in to a language dialect where signed integer
82-
and pointer overflow are well-defined.
82+
and pointer overflow are well-defined. Since Clang 20, it is also possible
83+
to use ``-fwrapv-pointer`` to only make pointer overflow well-defined, while
84+
not affecting the behavior of signed integer overflow.
85+
86+
- The ``-fwrapv`` flag now only makes signed integer overflow well-defined,
87+
without affecting pointer overflow, which is controlled by a new
88+
``-fwrapv-pointer`` flag. The ``-fno-strict-overflow`` flag now implies
89+
both ``-fwrapv`` and ``-fwrapv-pointer`` and as such retains its old meaning.
90+
The new behavior matches GCC.
8391

8492
C/C++ Language Potentially Breaking Changes
8593
-------------------------------------------
@@ -500,6 +508,11 @@ New Compiler Flags
500508
- clang-cl and clang-dxc now support ``-fdiagnostics-color=[auto|never|always]``
501509
in addition to ``-f[no-]color-diagnostics``.
502510

511+
- The new ``-fwrapv-pointer`` flag opts-in to a language dialect where pointer
512+
overflow is well-defined. The ``-fwrapv`` flag previously implied
513+
``-fwrapv-pointer`` as well, but no longer does. ``-fno-strict-overflow``
514+
implies ``-fwrapv -fwrapv-pointer``. The flags now match GCC.
515+
503516
Deprecated Compiler Flags
504517
-------------------------
505518

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
407407
"stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
408408
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
409409
"signed integer overflow handling")
410+
LANGOPT(PointerOverflowDefined, 1, 0, "make pointer overflow defined")
410411
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
411412

412413
BENIGN_LANGOPT(ArrowDepth, 32, 256,

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4299,6 +4299,11 @@ def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
42994299
HelpText<"Treat signed integer overflow as two's complement">;
43004300
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
43014301
Visibility<[ClangOption, CLOption, FlangOption]>;
4302+
def fwrapv_pointer : Flag<["-"], "fwrapv-pointer">, Group<f_Group>,
4303+
Visibility<[ClangOption, CLOption, CC1Option, FlangOption, FC1Option]>,
4304+
HelpText<"Treat pointer overflow as two's complement">;
4305+
def fno_wrapv_pointer : Flag<["-"], "fno-wrapv-pointer">, Group<f_Group>,
4306+
Visibility<[ClangOption, CLOption, FlangOption]>;
43024307
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
43034308
Visibility<[ClangOption, CC1Option]>,
43044309
HelpText<"Store string literals as writable data">,

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22051,7 +22051,7 @@ RValue CodeGenFunction::EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp) {
2205122051
// By adding the mask, we ensure that align_up on an already aligned
2205222052
// value will not change the value.
2205322053
if (Args.Src->getType()->isPointerTy()) {
22054-
if (getLangOpts().isSignedOverflowDefined())
22054+
if (getLangOpts().PointerOverflowDefined)
2205522055
SrcForMask =
2205622056
Builder.CreateGEP(Int8Ty, SrcForMask, Args.Mask, "over_boundary");
2205722057
else

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4311,14 +4311,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
43114311
// GEP indexes are signed, and scaling an index isn't permitted to
43124312
// signed-overflow, so we use the same semantics for our explicit
43134313
// multiply. We suppress this if overflow is not undefined behavior.
4314-
if (getLangOpts().isSignedOverflowDefined()) {
4314+
if (getLangOpts().PointerOverflowDefined) {
43154315
Idx = Builder.CreateMul(Idx, numElements);
43164316
} else {
43174317
Idx = Builder.CreateNSWMul(Idx, numElements);
43184318
}
43194319

43204320
Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(),
4321-
!getLangOpts().isSignedOverflowDefined(),
4321+
!getLangOpts().PointerOverflowDefined,
43224322
SignedIndices, E->getExprLoc());
43234323

43244324
} else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
@@ -4408,7 +4408,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
44084408
QualType arrayType = Array->getType();
44094409
Addr = emitArraySubscriptGEP(
44104410
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
4411-
E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
4411+
E->getType(), !getLangOpts().PointerOverflowDefined, SignedIndices,
44124412
E->getExprLoc(), &arrayType, E->getBase());
44134413
EltBaseInfo = ArrayLV.getBaseInfo();
44144414
EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
@@ -4417,10 +4417,9 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
44174417
Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
44184418
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
44194419
QualType ptrType = E->getBase()->getType();
4420-
Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
4421-
!getLangOpts().isSignedOverflowDefined(),
4422-
SignedIndices, E->getExprLoc(), &ptrType,
4423-
E->getBase());
4420+
Addr = emitArraySubscriptGEP(
4421+
*this, Addr, Idx, E->getType(), !getLangOpts().PointerOverflowDefined,
4422+
SignedIndices, E->getExprLoc(), &ptrType, E->getBase());
44244423
}
44254424

44264425
LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo);
@@ -4565,11 +4564,11 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
45654564
: llvm::ConstantInt::get(IntPtrTy, ConstLength);
45664565
Idx = Builder.CreateAdd(LowerBoundVal, LengthVal, "lb_add_len",
45674566
/*HasNUW=*/false,
4568-
!getLangOpts().isSignedOverflowDefined());
4567+
!getLangOpts().PointerOverflowDefined);
45694568
if (Length && LowerBound) {
45704569
Idx = Builder.CreateSub(
45714570
Idx, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "idx_sub_1",
4572-
/*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
4571+
/*HasNUW=*/false, !getLangOpts().PointerOverflowDefined);
45734572
}
45744573
} else
45754574
Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength + ConstLowerBound);
@@ -4595,7 +4594,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
45954594
Length->getType()->hasSignedIntegerRepresentation());
45964595
Idx = Builder.CreateSub(
45974596
LengthVal, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "len_sub_1",
4598-
/*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
4597+
/*HasNUW=*/false, !getLangOpts().PointerOverflowDefined);
45994598
} else {
46004599
ConstLength = ConstLength.zextOrTrunc(PointerWidthInBits);
46014600
--ConstLength;
@@ -4622,12 +4621,12 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
46224621
// GEP indexes are signed, and scaling an index isn't permitted to
46234622
// signed-overflow, so we use the same semantics for our explicit
46244623
// multiply. We suppress this if overflow is not undefined behavior.
4625-
if (getLangOpts().isSignedOverflowDefined())
4624+
if (getLangOpts().PointerOverflowDefined)
46264625
Idx = Builder.CreateMul(Idx, NumElements);
46274626
else
46284627
Idx = Builder.CreateNSWMul(Idx, NumElements);
46294628
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
4630-
!getLangOpts().isSignedOverflowDefined(),
4629+
!getLangOpts().PointerOverflowDefined,
46314630
/*signedIndices=*/false, E->getExprLoc());
46324631
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
46334632
// If this is A[i] where A is an array, the frontend will have decayed the
@@ -4647,7 +4646,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
46474646
// Propagate the alignment from the array itself to the result.
46484647
EltPtr = emitArraySubscriptGEP(
46494648
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
4650-
ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
4649+
ResultExprTy, !getLangOpts().PointerOverflowDefined,
46514650
/*signedIndices=*/false, E->getExprLoc());
46524651
BaseInfo = ArrayLV.getBaseInfo();
46534652
TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
@@ -4656,7 +4655,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
46564655
emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy,
46574656
ResultExprTy, IsLowerBound);
46584657
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
4659-
!getLangOpts().isSignedOverflowDefined(),
4658+
!getLangOpts().PointerOverflowDefined,
46604659
/*signedIndices=*/false, E->getExprLoc());
46614660
}
46624661

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,7 +3043,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
30433043
llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
30443044
if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
30453045
llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
3046-
if (CGF.getLangOpts().isSignedOverflowDefined())
3046+
if (CGF.getLangOpts().PointerOverflowDefined)
30473047
value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc");
30483048
else
30493049
value = CGF.EmitCheckedInBoundsGEP(
@@ -3054,7 +3054,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
30543054
} else if (type->isFunctionType()) {
30553055
llvm::Value *amt = Builder.getInt32(amount);
30563056

3057-
if (CGF.getLangOpts().isSignedOverflowDefined())
3057+
if (CGF.getLangOpts().PointerOverflowDefined)
30583058
value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
30593059
else
30603060
value =
@@ -3066,7 +3066,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
30663066
} else {
30673067
llvm::Value *amt = Builder.getInt32(amount);
30683068
llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
3069-
if (CGF.getLangOpts().isSignedOverflowDefined())
3069+
if (CGF.getLangOpts().PointerOverflowDefined)
30703070
value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr");
30713071
else
30723072
value = CGF.EmitCheckedInBoundsGEP(
@@ -3179,7 +3179,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
31793179
llvm::Value *sizeValue =
31803180
llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
31813181

3182-
if (CGF.getLangOpts().isSignedOverflowDefined())
3182+
if (CGF.getLangOpts().PointerOverflowDefined)
31833183
value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
31843184
else
31853185
value = CGF.EmitCheckedInBoundsGEP(
@@ -4075,7 +4075,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
40754075
// signed-overflow, so we use the same semantics for our explicit
40764076
// multiply. We suppress this if overflow is not undefined behavior.
40774077
llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
4078-
if (CGF.getLangOpts().isSignedOverflowDefined()) {
4078+
if (CGF.getLangOpts().PointerOverflowDefined) {
40794079
index = CGF.Builder.CreateMul(index, numElements, "vla.index");
40804080
pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
40814081
} else {
@@ -4096,7 +4096,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
40964096
else
40974097
elemTy = CGF.ConvertTypeForMem(elementType);
40984098

4099-
if (CGF.getLangOpts().isSignedOverflowDefined())
4099+
if (CGF.getLangOpts().PointerOverflowDefined)
41004100
return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
41014101

41024102
return CGF.EmitCheckedInBoundsGEP(

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
575575
options::OPT_fstrict_overflow, false);
576576
if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S))
577577
Add &= ~SanitizerKind::SignedIntegerOverflow;
578+
if (Args.hasFlagNoClaim(options::OPT_fwrapv_pointer,
579+
options::OPT_fno_wrapv_pointer, S))
580+
Add &= ~SanitizerKind::PointerOverflow;
578581
}
579582
Add &= Supported;
580583

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3106,12 +3106,19 @@ void tools::renderCommonIntegerOverflowOptions(const ArgList &Args,
31063106
ArgStringList &CmdArgs) {
31073107
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
31083108
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
3109+
bool StrictOverflow = Args.hasFlag(options::OPT_fstrict_overflow,
3110+
options::OPT_fno_strict_overflow, true);
31093111
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
31103112
if (A->getOption().matches(options::OPT_fwrapv))
31113113
CmdArgs.push_back("-fwrapv");
3112-
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
3113-
options::OPT_fno_strict_overflow)) {
3114-
if (A->getOption().matches(options::OPT_fno_strict_overflow))
3115-
CmdArgs.push_back("-fwrapv");
3114+
} else if (!StrictOverflow) {
3115+
CmdArgs.push_back("-fwrapv");
3116+
}
3117+
if (Arg *A = Args.getLastArg(options::OPT_fwrapv_pointer,
3118+
options::OPT_fno_wrapv_pointer)) {
3119+
if (A->getOption().matches(options::OPT_fwrapv_pointer))
3120+
CmdArgs.push_back("-fwrapv-pointer");
3121+
} else if (!StrictOverflow) {
3122+
CmdArgs.push_back("-fwrapv-pointer");
31163123
}
31173124
}

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,6 +3721,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
37213721
} else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
37223722
GenerateArg(Consumer, OPT_fwrapv);
37233723
}
3724+
if (Opts.PointerOverflowDefined)
3725+
GenerateArg(Consumer, OPT_fwrapv_pointer);
37243726

37253727
if (Opts.MSCompatibilityVersion != 0) {
37263728
unsigned Major = Opts.MSCompatibilityVersion / 10000000;
@@ -4138,6 +4140,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
41384140
}
41394141
else if (Args.hasArg(OPT_fwrapv))
41404142
Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
4143+
if (Args.hasArg(OPT_fwrapv_pointer))
4144+
Opts.PointerOverflowDefined = true;
41414145

41424146
Opts.MSCompatibilityVersion = 0;
41434147
if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11793,7 +11793,7 @@ static std::optional<bool> isTautologicalBoundsCheck(Sema &S, const Expr *LHS,
1179311793
const Expr *RHS,
1179411794
BinaryOperatorKind Opc) {
1179511795
if (!LHS->getType()->isPointerType() ||
11796-
S.getLangOpts().isSignedOverflowDefined())
11796+
S.getLangOpts().PointerOverflowDefined)
1179711797
return std::nullopt;
1179811798

1179911799
// Canonicalize to >= or < predicate.

clang/test/CodeGen/integer-overflow.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
22
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV
33
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
4-
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB,CATCH_UB_POINTER
5-
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow -fwrapv | FileCheck %s --check-prefixes=CATCH_UB,NOCATCH_UB_POINTER
4+
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB
5+
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow -fwrapv | FileCheck %s --check-prefixes=CATCH_UB
66
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER
77

88

@@ -57,15 +57,6 @@ void test1(void) {
5757
// TRAPV_HANDLER: foo(
5858
--a;
5959

60-
// -fwrapv should turn off inbounds for GEP's, PR9256
61-
extern int* P;
62-
++P;
63-
// DEFAULT: getelementptr inbounds nuw i32, ptr
64-
// WRAPV: getelementptr i32, ptr
65-
// TRAPV: getelementptr inbounds nuw i32, ptr
66-
// CATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr
67-
// NOCATCH_UB_POINTER: getelementptr i32, ptr
68-
6960
// PR9350: char pre-increment never overflows.
7061
extern volatile signed char PR9350_char_inc;
7162
// DEFAULT: add i8 {{.*}}, 1

clang/test/CodeGen/pointer-overflow.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
2+
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=DEFAULT
3+
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=DEFAULT
4+
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv-pointer | FileCheck %s --check-prefix=FWRAPV-POINTER
5+
6+
void test(void) {
7+
// -fwrapv-pointer should turn off inbounds for GEP's
8+
extern int* P;
9+
++P;
10+
// DEFAULT: getelementptr inbounds nuw i32, ptr
11+
// FWRAPV-POINTER: getelementptr i32, ptr
12+
}

clang/test/Driver/clang_wrapv_opts.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
// RUN: %clang -### -S -fwrapv -fno-wrapv -fwrapv %s 2>&1 | FileCheck -check-prefix=CHECK1 %s
22
// CHECK1: -fwrapv
33
//
4+
// RUN: %clang -### -S -fwrapv-pointer -fno-wrapv-pointer -fwrapv-pointer %s 2>&1 | FileCheck -check-prefix=CHECK1-POINTER %s
5+
// CHECK1-POINTER: -fwrapv-pointer
6+
//
47
// RUN: %clang -### -S -fstrict-overflow -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK2 %s
5-
// CHECK2: -fwrapv
8+
// CHECK2: -fwrapv{{.*}}-fwrapv-pointer
69
//
710
// RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s
811
// CHECK3: -fwrapv
912
//
13+
// RUN: %clang -### -S -fwrapv-pointer -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3-POINTER %s
14+
// CHECK3-POINTER: -fwrapv-pointer
15+
//
1016
// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK4 %s
1117
// CHECK4-NOT: -fwrapv
18+
// CHECK4: -fwrapv-pointer
19+
// CHECK4-NOT: -fwrapv
20+
//
21+
// RUN: %clang -### -S -fno-wrapv-pointer -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK4-POINTER %s
22+
// CHECK4-POINTER-NOT: -fwrapv-pointer
23+
// CHECK4-POINTER: -fwrapv
24+
// CHECK4-POINTER-NOT: -fwrapv-pointer

clang/test/Sema/tautological-pointer-comparison.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify %s
2-
// RUN: %clang_cc1 -fsyntax-only -fwrapv -verify=fwrapv %s
2+
// RUN: %clang_cc1 -fsyntax-only -fwrapv-pointer -verify=fwrapv %s
33

44
// fwrapv-no-diagnostics
55

0 commit comments

Comments
 (0)