[clang] [Clang] Add -fwrapv-pointer flag (PR #122486)
Nikita Popov via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 10 08:16:17 PST 2025
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/122486
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).
>From 32fe619505787c434f97b01da0458ba7861f9550 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 10 Jan 2025 17:01:07 +0100
Subject: [PATCH] [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).
---
clang/docs/ReleaseNotes.rst | 11 ++++++++++
clang/include/clang/Basic/LangOptions.def | 1 +
clang/include/clang/Driver/Options.td | 5 +++++
clang/lib/CodeGen/CGBuiltin.cpp | 2 +-
clang/lib/CodeGen/CGExpr.cpp | 22 +++++++++----------
clang/lib/CodeGen/CGExprScalar.cpp | 12 +++++-----
clang/lib/Driver/SanitizerArgs.cpp | 3 +++
clang/lib/Driver/ToolChains/CommonArgs.cpp | 15 +++++++++----
clang/lib/Frontend/CompilerInvocation.cpp | 4 ++++
clang/lib/Sema/SemaExpr.cpp | 2 +-
clang/test/CodeGen/integer-overflow.c | 13 ++---------
clang/test/Driver/clang_wrapv_opts.c | 19 +++++++++++++---
.../Sema/tautological-pointer-comparison.c | 2 +-
13 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 511a28c5554bbb..44d98d98411d12 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -58,6 +58,12 @@ code bases.
containing strict-aliasing violations. The new default behavior can be
disabled using ``-fno-pointer-tbaa``.
+- The ``-fwrapv`` flag now only makes signed integer overflow well-defined,
+ without affecting pointer overflow, which is controlled by a new
+ ``-fwrapv-pointer`` flag. The ``-fno-strict-overflow`` flag now implies
+ both ``-fwrapv`` and ``-fwrapv-pointer`` and as such retains its old meaning.
+ The new behavior matches GCC.
+
C/C++ Language Potentially Breaking Changes
-------------------------------------------
@@ -464,6 +470,11 @@ New Compiler Flags
- clang-cl and clang-dxc now support ``-fdiagnostics-color=[auto|never|always]``
in addition to ``-f[no-]color-diagnostics``.
+- The new ``-fwrapv-pointer`` flag opts-in to a language dialect where pointer
+ overflow is well-defined. The ``-fwrapv`` flag previously implied
+ ``-fwrapv-pointer`` as well, but no longer does. ``-fno-strict-overflow``
+ implies ``-fwrapv -fwrapv-pointer``. The flags now match GCC.
+
Deprecated Compiler Flags
-------------------------
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 3b833240e5b68c..c4c53d7455c417 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -407,6 +407,7 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
"stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
+LANGOPT(PointerOverflowDefined, 1, 0, "make pointer overflow defined")
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
BENIGN_LANGOPT(ArrowDepth, 32, 256,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 41a7e8c3728066..8b45aa6dd4c2df 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4291,6 +4291,11 @@ def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
HelpText<"Treat signed integer overflow as two's complement">;
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
Visibility<[ClangOption, CLOption, FlangOption]>;
+def fwrapv_pointer : Flag<["-"], "fwrapv-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, CC1Option, FlangOption, FC1Option]>,
+ HelpText<"Treat pointer overflow as two's complement">;
+def fno_wrapv_pointer : Flag<["-"], "fno-wrapv-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, FlangOption]>;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Store string literals as writable data">,
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index ca03fb665d423d..b5bbfeae576029 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -22113,7 +22113,7 @@ RValue CodeGenFunction::EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp) {
// By adding the mask, we ensure that align_up on an already aligned
// value will not change the value.
if (Args.Src->getType()->isPointerTy()) {
- if (getLangOpts().isSignedOverflowDefined())
+ if (getLangOpts().PointerOverflowDefined)
SrcForMask =
Builder.CreateGEP(Int8Ty, SrcForMask, Args.Mask, "over_boundary");
else
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1bad7a722da07a..dc9c2afeaa93a5 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4307,14 +4307,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// GEP indexes are signed, and scaling an index isn't permitted to
// signed-overflow, so we use the same semantics for our explicit
// multiply. We suppress this if overflow is not undefined behavior.
- if (getLangOpts().isSignedOverflowDefined()) {
+ if (getLangOpts().PointerOverflowDefined) {
Idx = Builder.CreateMul(Idx, numElements);
} else {
Idx = Builder.CreateNSWMul(Idx, numElements);
}
Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(),
- !getLangOpts().isSignedOverflowDefined(),
+ !getLangOpts().PointerOverflowDefined,
SignedIndices, E->getExprLoc());
} else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
@@ -4404,7 +4404,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
QualType arrayType = Array->getType();
Addr = emitArraySubscriptGEP(
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
- E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
+ E->getType(), !getLangOpts().PointerOverflowDefined, SignedIndices,
E->getExprLoc(), &arrayType, E->getBase());
EltBaseInfo = ArrayLV.getBaseInfo();
EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
@@ -4414,7 +4414,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
QualType ptrType = E->getBase()->getType();
Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
- !getLangOpts().isSignedOverflowDefined(),
+ !getLangOpts().PointerOverflowDefined,
SignedIndices, E->getExprLoc(), &ptrType,
E->getBase());
}
@@ -4561,11 +4561,11 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
: llvm::ConstantInt::get(IntPtrTy, ConstLength);
Idx = Builder.CreateAdd(LowerBoundVal, LengthVal, "lb_add_len",
/*HasNUW=*/false,
- !getLangOpts().isSignedOverflowDefined());
+ !getLangOpts().PointerOverflowDefined);
if (Length && LowerBound) {
Idx = Builder.CreateSub(
Idx, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "idx_sub_1",
- /*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
+ /*HasNUW=*/false, !getLangOpts().PointerOverflowDefined);
}
} else
Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength + ConstLowerBound);
@@ -4591,7 +4591,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
Length->getType()->hasSignedIntegerRepresentation());
Idx = Builder.CreateSub(
LengthVal, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "len_sub_1",
- /*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
+ /*HasNUW=*/false, !getLangOpts().PointerOverflowDefined);
} else {
ConstLength = ConstLength.zextOrTrunc(PointerWidthInBits);
--ConstLength;
@@ -4618,12 +4618,12 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
// GEP indexes are signed, and scaling an index isn't permitted to
// signed-overflow, so we use the same semantics for our explicit
// multiply. We suppress this if overflow is not undefined behavior.
- if (getLangOpts().isSignedOverflowDefined())
+ if (getLangOpts().PointerOverflowDefined)
Idx = Builder.CreateMul(Idx, NumElements);
else
Idx = Builder.CreateNSWMul(Idx, NumElements);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
- !getLangOpts().isSignedOverflowDefined(),
+ !getLangOpts().PointerOverflowDefined,
/*signedIndices=*/false, E->getExprLoc());
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
// If this is A[i] where A is an array, the frontend will have decayed the
@@ -4643,7 +4643,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
// Propagate the alignment from the array itself to the result.
EltPtr = emitArraySubscriptGEP(
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
- ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
+ ResultExprTy, !getLangOpts().PointerOverflowDefined,
/*signedIndices=*/false, E->getExprLoc());
BaseInfo = ArrayLV.getBaseInfo();
TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
@@ -4652,7 +4652,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy,
ResultExprTy, IsLowerBound);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
- !getLangOpts().isSignedOverflowDefined(),
+ !getLangOpts().PointerOverflowDefined,
/*signedIndices=*/false, E->getExprLoc());
}
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 090c4fb3ea39ee..32395391000ffb 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3037,7 +3037,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
- if (CGF.getLangOpts().isSignedOverflowDefined())
+ if (CGF.getLangOpts().PointerOverflowDefined)
value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc");
else
value = CGF.EmitCheckedInBoundsGEP(
@@ -3048,7 +3048,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
} else if (type->isFunctionType()) {
llvm::Value *amt = Builder.getInt32(amount);
- if (CGF.getLangOpts().isSignedOverflowDefined())
+ if (CGF.getLangOpts().PointerOverflowDefined)
value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
else
value =
@@ -3060,7 +3060,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
} else {
llvm::Value *amt = Builder.getInt32(amount);
llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
- if (CGF.getLangOpts().isSignedOverflowDefined())
+ if (CGF.getLangOpts().PointerOverflowDefined)
value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr");
else
value = CGF.EmitCheckedInBoundsGEP(
@@ -3173,7 +3173,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
llvm::Value *sizeValue =
llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
- if (CGF.getLangOpts().isSignedOverflowDefined())
+ if (CGF.getLangOpts().PointerOverflowDefined)
value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
else
value = CGF.EmitCheckedInBoundsGEP(
@@ -4067,7 +4067,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
// signed-overflow, so we use the same semantics for our explicit
// multiply. We suppress this if overflow is not undefined behavior.
llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
- if (CGF.getLangOpts().isSignedOverflowDefined()) {
+ if (CGF.getLangOpts().PointerOverflowDefined) {
index = CGF.Builder.CreateMul(index, numElements, "vla.index");
pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
} else {
@@ -4088,7 +4088,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
else
elemTy = CGF.ConvertTypeForMem(elementType);
- if (CGF.getLangOpts().isSignedOverflowDefined())
+ if (CGF.getLangOpts().PointerOverflowDefined)
return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
return CGF.EmitCheckedInBoundsGEP(
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index a0d6919c6dc8d0..3420472c0f75eb 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -575,6 +575,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
options::OPT_fstrict_overflow, false);
if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S))
Add &= ~SanitizerKind::SignedIntegerOverflow;
+ if (Args.hasFlagNoClaim(options::OPT_fwrapv_pointer,
+ options::OPT_fno_wrapv_pointer, S))
+ Add &= ~SanitizerKind::PointerOverflow;
}
Add &= Supported;
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index f8967890f722cf..8f5c38b38c2f8d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -3106,12 +3106,19 @@ void tools::renderCommonIntegerOverflowOptions(const ArgList &Args,
ArgStringList &CmdArgs) {
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
+ bool StrictOverflow = Args.hasFlag(options::OPT_fstrict_overflow,
+ options::OPT_fno_strict_overflow, true);
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
if (A->getOption().matches(options::OPT_fwrapv))
CmdArgs.push_back("-fwrapv");
- } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
- options::OPT_fno_strict_overflow)) {
- if (A->getOption().matches(options::OPT_fno_strict_overflow))
- CmdArgs.push_back("-fwrapv");
+ } else if (!StrictOverflow) {
+ CmdArgs.push_back("-fwrapv");
+ }
+ if (Arg *A = Args.getLastArg(options::OPT_fwrapv_pointer,
+ options::OPT_fno_wrapv_pointer)) {
+ if (A->getOption().matches(options::OPT_fwrapv_pointer))
+ CmdArgs.push_back("-fwrapv-pointer");
+ } else if (!StrictOverflow) {
+ CmdArgs.push_back("-fwrapv-pointer");
}
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 39bed84536c6a3..2acb4e49dba70b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3721,6 +3721,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
} else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
GenerateArg(Consumer, OPT_fwrapv);
}
+ if (Opts.PointerOverflowDefined)
+ GenerateArg(Consumer, OPT_fwrapv_pointer);
if (Opts.MSCompatibilityVersion != 0) {
unsigned Major = Opts.MSCompatibilityVersion / 10000000;
@@ -4138,6 +4140,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
}
else if (Args.hasArg(OPT_fwrapv))
Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
+ if (Args.hasArg(OPT_fwrapv_pointer))
+ Opts.PointerOverflowDefined = true;
Opts.MSCompatibilityVersion = 0;
if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ae40895980d90a..4920688dff398e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11787,7 +11787,7 @@ static std::optional<bool> isTautologicalBoundsCheck(Sema &S, const Expr *LHS,
const Expr *RHS,
BinaryOperatorKind Opc) {
if (!LHS->getType()->isPointerType() ||
- S.getLangOpts().isSignedOverflowDefined())
+ S.getLangOpts().PointerOverflowDefined)
return std::nullopt;
// Canonicalize to >= or < predicate.
diff --git a/clang/test/CodeGen/integer-overflow.c b/clang/test/CodeGen/integer-overflow.c
index 9e8cde8b33b16e..9f1eca7e314c26 100644
--- a/clang/test/CodeGen/integer-overflow.c
+++ b/clang/test/CodeGen/integer-overflow.c
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
-// 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
-// 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
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow -fwrapv | FileCheck %s --check-prefixes=CATCH_UB
// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER
@@ -57,15 +57,6 @@ void test1(void) {
// TRAPV_HANDLER: foo(
--a;
- // -fwrapv should turn off inbounds for GEP's, PR9256
- extern int* P;
- ++P;
- // DEFAULT: getelementptr inbounds nuw i32, ptr
- // WRAPV: getelementptr i32, ptr
- // TRAPV: getelementptr inbounds nuw i32, ptr
- // CATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr
- // NOCATCH_UB_POINTER: getelementptr i32, ptr
-
// PR9350: char pre-increment never overflows.
extern volatile signed char PR9350_char_inc;
// DEFAULT: add i8 {{.*}}, 1
diff --git a/clang/test/Driver/clang_wrapv_opts.c b/clang/test/Driver/clang_wrapv_opts.c
index 826468e0678d0b..c0045b95639b31 100644
--- a/clang/test/Driver/clang_wrapv_opts.c
+++ b/clang/test/Driver/clang_wrapv_opts.c
@@ -1,11 +1,24 @@
// RUN: %clang -### -S -fwrapv -fno-wrapv -fwrapv %s 2>&1 | FileCheck -check-prefix=CHECK1 %s
// CHECK1: -fwrapv
//
+// RUN: %clang -### -S -fwrapv-pointer -fno-wrapv-pointer -fwrapv-pointer %s 2>&1 | FileCheck -check-prefix=CHECK1-POINTER %s
+// CHECK1-POINTER: -fwrapv-pointer
+//
// RUN: %clang -### -S -fstrict-overflow -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK2 %s
-// CHECK2: -fwrapv
+// CHECK2: -fwrapv{{.*}}-fwrapv-pointer
//
// RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s
// CHECK3: -fwrapv
//
-// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK4 %s
-// CHECK4-NOT: -fwrapv
+// RUN: %clang -### -S -fwrapv-pointer -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3-POINTER %s
+// CHECK3-POINTER: -fwrapv-pointer
+//
+// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK5 %s
+// CHECK5-NOT: -fwrapv
+// CHECK5: -fwrapv-pointer
+// CHECK5-NOT: -fwrapv
+//
+// RUN: %clang -### -S -fno-wrapv-pointer -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK5-POINTER %s
+// CHECK5-POINTER-NOT: -fwrapv-pointer
+// CHECK5-POINTER: -fwrapv
+// CHECK5-POINTER-NOT: -fwrapv-pointer
diff --git a/clang/test/Sema/tautological-pointer-comparison.c b/clang/test/Sema/tautological-pointer-comparison.c
index 1c5973b01a30d0..f2a944b5305e4e 100644
--- a/clang/test/Sema/tautological-pointer-comparison.c
+++ b/clang/test/Sema/tautological-pointer-comparison.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fwrapv -verify=fwrapv %s
+// RUN: %clang_cc1 -fsyntax-only -fwrapv-pointer -verify=fwrapv %s
// fwrapv-no-diagnostics
More information about the cfe-commits
mailing list