-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Assert the enum FPOpts and LangOpts fit into the storage #126166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Assert the enum FPOpts and LangOpts fit into the storage #126166
Conversation
Created using spr 1.3.4
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-clang Author: Florian Mayer (fmayer) ChangesFix existing failure Full diff: https://github.com/llvm/llvm-project/pull/126166.diff 3 Files Affected:
diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def
index 79f04c89c9fedc..90428c3c73c8b5 100644
--- a/clang/include/clang/Basic/FPOptions.def
+++ b/clang/include/clang/Basic/FPOptions.def
@@ -28,5 +28,5 @@ OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc)
OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod)
OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, Float16ExcessPrecision)
OPTION(MathErrno, bool, 1, BFloat16ExcessPrecision)
-OPTION(ComplexRange, LangOptions::ComplexRangeKind, 2, MathErrno)
+OPTION(ComplexRange, LangOptions::ComplexRangeKind, 3, MathErrno)
#undef OPTION
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index cb55f09acc076c..bfab0baa089cf7 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -238,7 +238,7 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit
BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
-ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_None, "Enable use of range reduction for complex arithmetics.")
+ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 3, CX_None, "Enable use of range reduction for complex arithmetics.")
BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index f58a719a45a84d..95c1555179781d 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -648,9 +648,12 @@ class LangOptions : public LangOptionsBase {
// Define accessors/mutators for language options of enumeration type.
#define LANGOPT(Name, Bits, Default, Description)
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- Type get##Name() const { return static_cast<Type>(Name); } \
- void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ Type get##Name() const { return static_cast<Type>(Name); } \
+ void set##Name(Type Value) { \
+ assert(static_cast<unsigned>(Value) < (1u << Bits)); \
+ Name = static_cast<unsigned>(Value); \
+ }
#include "clang/Basic/LangOptions.def"
/// Are we compiling a module?
@@ -964,6 +967,7 @@ class FPOptions {
return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \
} \
void set##NAME(TYPE value) { \
+ assert(storage_type(value) < (1u << WIDTH)); \
Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \
}
#include "clang/Basic/FPOptions.def"
|
The only valid values for the |
Then why does this assertion trigger if I don't pass anything? |
Not sure I understand your question? |
I don't understand why you say
but imply it does not need to be stored in the bitfield. If you patch this CL, and change the size for |
OK. I see the issue. Thanks. |
What do you mean? Of course you can't fail the assertion now that the offending code is fixed. |
I added your patch to my code base (added only the assert, didn't change the size of storage for However the rule is that every patch needs at least one LIT test that illustrates the issue and prove that your patch fixes it. You don't have a LIT test in your patch. So, you can either make this patch |
Just adding the This patch is not NFC because it fixes buggy behaviour. If you look closely, your None value actually overflowed into unrelated bits for the FpOpts, causing who knows what behavior to change. |
The idea here makes sense to me and I don't mind if it lands without "NFC" in the title, but I think enforcing this at compile time would be more robust. Could we use |
That would involve annotating all the enums with the largest value, and that's a bigger change, and also prone to error, so even if we did this the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, makes sense to fix the immediate problem now and follow up with the more robust fix later. Would be good if you could leave a FIXME on one of the assert
calls in LangOptions.h
outlining the potential improvement via static_assert
. LGTM
…m#126166) Fix existing failure
…m#126166) Fix existing failure
…m#126166) Fix existing failure
…m#126166) Fix existing failure
Fix existing failure