aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Driver/CC1Options.td3
-rw-r--r--include/clang/Driver/Options.td2
-rw-r--r--include/clang/Frontend/CodeGenOptions.h2
-rw-r--r--lib/CodeGen/CGExpr.cpp5
-rw-r--r--lib/Driver/Tools.cpp3
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--test/CodeGenCXX/pr12251.cpp9
7 files changed, 24 insertions, 3 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 46c4ed89b5..956f2a65ce 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -178,6 +178,9 @@ def ffunction_sections : Flag<"-ffunction-sections">,
HelpText<"Place each function in its own section (ELF Only)">;
def fdata_sections : Flag<"-fdata-sections">,
HelpText<"Place each data in its own section (ELF Only)">;
+def fstrict_enums : Flag<"-fstrict-enums">,
+ HelpText<"Enable optimizations based on the strict definition of an enum's "
+ "value range.">;
def ftrap_function_EQ : Joined<"-ftrap-function=">,
HelpText<"Issue call to specified function rather than a trap instruction">;
def funroll_loops : Flag<"-funroll-loops">,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index eab8e8f331..6bc0a7d0b5 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -444,6 +444,7 @@ def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>
def fno_spell_checking : Flag<"-fno-spell-checking">, Group<f_Group>;
def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<f_Group>;
+def fno_strict_enums : Flag<"-fno-strict-enums">, Group<f_Group>;
def fno_strict_overflow : Flag<"-fno-strict-overflow">, Group<f_Group>;
def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>;
@@ -515,6 +516,7 @@ def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<f_Group>;
+def fstrict_enums : Flag<"-fstrict-enums">, Group<f_Group>;
def fstrict_overflow : Flag<"-fstrict-overflow">, Group<f_Group>;
def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 59509331a0..e844f8869c 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -94,6 +94,7 @@ public:
unsigned SaveTempLabels : 1; /// Save temporary labels.
unsigned SimplifyLibCalls : 1; /// Set when -fbuiltin is enabled.
unsigned SoftFloat : 1; /// -soft-float.
+ unsigned StrictEnums : 1; /// Optimize based on strict enum definition.
unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
/// selection.
@@ -205,6 +206,7 @@ public:
SaveTempLabels = 0;
SimplifyLibCalls = 1;
SoftFloat = 0;
+ StrictEnums = 0;
TimePasses = 0;
UnitAtATime = 1;
UnrollLoops = 0;
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index a9f87e67d4..511914884f 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -872,8 +872,9 @@ static bool hasBooleanRepresentation(QualType Ty) {
llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
const EnumType *ET = Ty->getAs<EnumType>();
- bool IsRegularCPlusPlusEnum = getLangOpts().CPlusPlus && ET &&
- !ET->getDecl()->isFixed();
+ bool IsRegularCPlusPlusEnum = (getLangOpts().CPlusPlus && ET &&
+ CGM.getCodeGenOpts().StrictEnums &&
+ !ET->getDecl()->isFixed());
bool IsBool = hasBooleanRepresentation(Ty);
llvm::Type *LTy;
if (!IsBool && !IsRegularCPlusPlusEnum)
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 52c22b13a4..ff034d685d 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1487,6 +1487,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_strict_aliasing,
getToolChain().IsStrictAliasingDefault()))
CmdArgs.push_back("-relaxed-aliasing");
+ if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
+ false))
+ CmdArgs.push_back("-fstrict-enums");
if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
options::OPT_fno_optimize_sibling_calls))
CmdArgs.push_back("-mdisable-tail-calls");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 0f68591c96..48b8049cd0 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -286,6 +286,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, ToArgsList &Res) {
Res.push_back("-fno-dwarf-directory-asm");
if (Opts.SoftFloat)
Res.push_back("-msoft-float");
+ if (Opts.StrictEnums)
+ Res.push_back("-fstrict-enums");
if (Opts.UnwindTables)
Res.push_back("-munwind-tables");
if (Opts.RelocationModel != "pic")
@@ -1135,6 +1137,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.NoDwarf2CFIAsm = Args.hasArg(OPT_fno_dwarf2_cfi_asm);
Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
+ Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
diff --git a/test/CodeGenCXX/pr12251.cpp b/test/CodeGenCXX/pr12251.cpp
index 310e60d3e5..a9920c0733 100644
--- a/test/CodeGenCXX/pr12251.cpp
+++ b/test/CodeGenCXX/pr12251.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -fstrict-enums -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -std=c++11 -o - | FileCheck --check-prefix=NO-STRICT-ENUMS %s
bool f(bool *x) {
return *x;
@@ -6,6 +7,12 @@ bool f(bool *x) {
// CHECK: define zeroext i1 @_Z1fPb
// CHECK: load i8* %{{.*}}, align 1, !range !0
+// Only enum-tests follow. Ensure that after the bool test, no further range
+// metadata shows up when strict enums are disabled.
+// NO-STRICT-ENUMS: define zeroext i1 @_Z1fPb
+// NO-STRICT-ENUMS: load i8* %{{.*}}, align 1, !range !0
+// NO-STRICT-ENUMS-NOT: !range
+
enum e1 { };
e1 g1(e1 *x) {
return *x;