Skip to content

Commit c3547f9

Browse files
committed
Merge remote-tracking branch 'origin/main' into perf/aballman-gh21898
2 parents c0fbe17 + e8ae779 commit c3547f9

File tree

104 files changed

+1720
-699
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+1720
-699
lines changed

bolt/docs/BinaryAnalysis.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,6 @@ The following are current known cases of false negatives:
180180
[prototype branch](
181181
https://github.com/llvm/llvm-project/compare/main...kbeyls:llvm-project:bolt-gadget-scanner-prototype).
182182

183-
BOLT cannot currently handle functions with `cfi_negate_ra_state` correctly,
184-
i.e. any binaries built with `-mbranch-protection=pac-ret`. The scanner is meant
185-
to be used on specifically such binaries, so this is a major limitation! Work is
186-
going on in PR [#120064](https://github.com/llvm/llvm-project/pull/120064) to
187-
fix this.
188-
189183
## How to add your own binary analysis
190184

191185
_TODO: this section needs to be written. Ideally, we should have a simple

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ extern cl::opt<bool> StrictMode;
6565
extern cl::opt<bool> UpdateDebugSections;
6666
extern cl::opt<unsigned> Verbosity;
6767

68+
extern bool BinaryAnalysisMode;
69+
extern bool HeatmapMode;
6870
extern bool processAllFunctions();
6971

7072
static cl::opt<bool> CheckEncoding(
@@ -2760,13 +2762,19 @@ struct CFISnapshot {
27602762
}
27612763
case MCCFIInstruction::OpAdjustCfaOffset:
27622764
case MCCFIInstruction::OpWindowSave:
2763-
case MCCFIInstruction::OpNegateRAState:
27642765
case MCCFIInstruction::OpNegateRAStateWithPC:
27652766
case MCCFIInstruction::OpLLVMDefAspaceCfa:
27662767
case MCCFIInstruction::OpLabel:
27672768
case MCCFIInstruction::OpValOffset:
27682769
llvm_unreachable("unsupported CFI opcode");
27692770
break;
2771+
case MCCFIInstruction::OpNegateRAState:
2772+
if (!(opts::BinaryAnalysisMode || opts::HeatmapMode)) {
2773+
llvm_unreachable("BOLT-ERROR: binaries using pac-ret hardening (e.g. "
2774+
"as produced by '-mbranch-protection=pac-ret') are "
2775+
"currently not supported by BOLT.");
2776+
}
2777+
break;
27702778
case MCCFIInstruction::OpRememberState:
27712779
case MCCFIInstruction::OpRestoreState:
27722780
case MCCFIInstruction::OpGnuArgsSize:
@@ -2900,13 +2908,19 @@ struct CFISnapshotDiff : public CFISnapshot {
29002908
return CFAReg == Instr.getRegister() && CFAOffset == Instr.getOffset();
29012909
case MCCFIInstruction::OpAdjustCfaOffset:
29022910
case MCCFIInstruction::OpWindowSave:
2903-
case MCCFIInstruction::OpNegateRAState:
29042911
case MCCFIInstruction::OpNegateRAStateWithPC:
29052912
case MCCFIInstruction::OpLLVMDefAspaceCfa:
29062913
case MCCFIInstruction::OpLabel:
29072914
case MCCFIInstruction::OpValOffset:
29082915
llvm_unreachable("unsupported CFI opcode");
29092916
return false;
2917+
case MCCFIInstruction::OpNegateRAState:
2918+
if (!(opts::BinaryAnalysisMode || opts::HeatmapMode)) {
2919+
llvm_unreachable("BOLT-ERROR: binaries using pac-ret hardening (e.g. "
2920+
"as produced by '-mbranch-protection=pac-ret') are "
2921+
"currently not supported by BOLT.");
2922+
}
2923+
break;
29102924
case MCCFIInstruction::OpRememberState:
29112925
case MCCFIInstruction::OpRestoreState:
29122926
case MCCFIInstruction::OpGnuArgsSize:
@@ -3051,13 +3065,19 @@ BinaryFunction::unwindCFIState(int32_t FromState, int32_t ToState,
30513065
break;
30523066
case MCCFIInstruction::OpAdjustCfaOffset:
30533067
case MCCFIInstruction::OpWindowSave:
3054-
case MCCFIInstruction::OpNegateRAState:
30553068
case MCCFIInstruction::OpNegateRAStateWithPC:
30563069
case MCCFIInstruction::OpLLVMDefAspaceCfa:
30573070
case MCCFIInstruction::OpLabel:
30583071
case MCCFIInstruction::OpValOffset:
30593072
llvm_unreachable("unsupported CFI opcode");
30603073
break;
3074+
case MCCFIInstruction::OpNegateRAState:
3075+
if (!(opts::BinaryAnalysisMode || opts::HeatmapMode)) {
3076+
llvm_unreachable("BOLT-ERROR: binaries using pac-ret hardening (e.g. "
3077+
"as produced by '-mbranch-protection=pac-ret') are "
3078+
"currently not supported by BOLT.");
3079+
}
3080+
break;
30613081
case MCCFIInstruction::OpGnuArgsSize:
30623082
// do not affect CFI state
30633083
break;

clang/docs/ReleaseNotes.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,23 @@ C Language Changes
173173
``-Wenum-conversion`` and ``-Wimplicit-int-enum-cast``. This conversion is an
174174
int-to-enum conversion because the enumeration on the right-hand side is
175175
promoted to ``int`` before the assignment.
176+
- Added ``-Wunterminated-string-initialization``, grouped under ``-Wextra``,
177+
which diagnoses an initialization from a string literal where only the null
178+
terminator cannot be stored. e.g.,
179+
180+
.. code-block:: c
181+
182+
183+
char buf1[3] = "foo"; // -Wunterminated-string-initialization
184+
char buf2[3] = "flarp"; // -Wexcess-initializers
185+
186+
This diagnostic can be suppressed by adding the new ``nonstring`` attribute
187+
to the field or variable being initialized. #GH137705
188+
- Added ``-Wc++-unterminated-string-initialization``, grouped under
189+
``-Wc++-compat``, which also diagnoses the same cases as
190+
``-Wunterminated-string-initialization``. However, this diagnostic is not
191+
silenced by the ``nonstring`` attribute as these initializations are always
192+
incompatible with C++.
176193

177194
C2y Feature Support
178195
^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/Attr.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5024,3 +5024,9 @@ def OpenACCRoutineDecl :InheritableAttr {
50245024
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const;
50255025
}];
50265026
}
5027+
5028+
def NonString : InheritableAttr {
5029+
let Spellings = [GCC<"nonstring">];
5030+
let Subjects = SubjectList<[Var, Field]>;
5031+
let Documentation = [NonStringDocs];
5032+
}

clang/include/clang/Basic/AttrDocs.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9294,3 +9294,18 @@ Declares that a function potentially allocates heap memory, and prevents any pot
92949294
of ``nonallocating`` by the compiler.
92959295
}];
92969296
}
9297+
9298+
def NonStringDocs : Documentation {
9299+
let Category = DocCatDecl;
9300+
let Content = [{
9301+
The ``nonstring`` attribute can be applied to the declaration of a variable or
9302+
a field whose type is a character array to specify that the character array is
9303+
not intended to behave like a null-terminated string. This will silence
9304+
diagnostics with code like:
9305+
9306+
.. code-block:: c
9307+
9308+
char BadStr[3] = "foo"; // No space for the null terminator, diagnosed
9309+
__attribute__((nonstring)) char NotAStr[3] = "foo"; // Not diagnosed
9310+
}];
9311+
}

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ def C99Compat : DiagGroup<"c99-compat">;
157157
def C23Compat : DiagGroup<"c23-compat">;
158158
def : DiagGroup<"c2x-compat", [C23Compat]>;
159159
def CppKeywordInC : DiagGroup<"c++-keyword">;
160+
def InitStringTooLongMissingNonString :
161+
DiagGroup<"unterminated-string-initialization">;
162+
def InitStringTooLongForCpp :
163+
DiagGroup<"c++-unterminated-string-initialization">;
160164
def HiddenCppDecl : DiagGroup<"c++-hidden-decl">;
161165
def DefaultConstInitUnsafe : DiagGroup<"default-const-init-unsafe">;
162166
def DefaultConstInit : DiagGroup<"default-const-init", [DefaultConstInitUnsafe]>;
@@ -165,6 +169,7 @@ def ImplicitIntToEnumCast : DiagGroup<"implicit-int-enum-cast",
165169
[ImplicitEnumEnumCast]>;
166170
def CXXCompat: DiagGroup<"c++-compat", [ImplicitVoidPtrCast, DefaultConstInit,
167171
ImplicitIntToEnumCast, CppKeywordInC,
172+
InitStringTooLongForCpp,
168173
HiddenCppDecl]>;
169174

170175
def ExternCCompat : DiagGroup<"extern-c-compat">;
@@ -1145,6 +1150,7 @@ def Extra : DiagGroup<"extra", [
11451150
StringConcatation,
11461151
FUseLdPath,
11471152
CastFunctionTypeMismatch,
1153+
InitStringTooLongMissingNonString,
11481154
]>;
11491155

11501156
def Most : DiagGroup<"most", [

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3804,6 +3804,9 @@ def err_attribute_weakref_without_alias : Error<
38043804
"weakref declaration of %0 must also have an alias attribute">;
38053805
def err_alias_not_supported_on_darwin : Error <
38063806
"aliases are not supported on darwin">;
3807+
def warn_attribute_non_character_array : Warning<
3808+
"%0%select{ attribute|}1 only applies to fields or variables of character "
3809+
"array type; type is %2">, InGroup<IgnoredAttributes>;
38073810
def warn_attribute_wrong_decl_type_str : Warning<
38083811
"%0%select{ attribute|}1 only applies to %2">, InGroup<IgnoredAttributes>;
38093812
def err_attribute_wrong_decl_type_str : Error<
@@ -6404,6 +6407,15 @@ def err_initializer_string_for_char_array_too_long : Error<
64046407
def ext_initializer_string_for_char_array_too_long : ExtWarn<
64056408
"initializer-string for char array is too long">,
64066409
InGroup<ExcessInitializers>;
6410+
def warn_initializer_string_for_char_array_too_long_no_nonstring : Warning<
6411+
"initializer-string for character array is too long, array size is %0 but "
6412+
"initializer has size %1 (including the null terminating character); did you "
6413+
"mean to use the 'nonstring' attribute?">,
6414+
InGroup<InitStringTooLongMissingNonString>, DefaultIgnore;
6415+
def warn_initializer_string_for_char_array_too_long_for_cpp : Warning<
6416+
"initializer-string for character array is too long for C++, array size is "
6417+
"%0 but initializer has size %1 (including the null terminating character)">,
6418+
InGroup<InitStringTooLongForCpp>, DefaultIgnore;
64076419
def warn_missing_field_initializers : Warning<
64086420
"missing field %0 initializer">,
64096421
InGroup<MissingFieldInitializers>, DefaultIgnore;

clang/include/clang/Basic/LangOptions.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,21 @@ BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contracti
347347
COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point")
348348
BENIGN_LANGOPT(RoundingMath, 1, false, "Do not assume default floating-point rounding behavior")
349349
BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Default, "FP Exception Behavior Mode type")
350+
351+
#if defined(__clang__) && defined(__has_warning)
352+
#if __has_warning("-Wpreferred-type-bitfield-enum-conversion")
353+
// FIXME: Remove this once the warning is fixed, https://llvm.org/PR137600
354+
#pragma clang diagnostic push
355+
#pragma clang diagnostic ignored "-Wpreferred-type-bitfield-enum-conversion"
356+
#endif
357+
#endif
350358
BENIGN_ENUM_LANGOPT(FPEvalMethod, FPEvalMethodKind, 3, FEM_UnsetOnCommandLine, "FP type used for floating point arithmetic")
359+
#if defined(__clang__) && defined(__has_warning)
360+
#if __has_warning("-Wpreferred-type-bitfield-enum-conversion")
361+
#pragma clang diagnostic pop
362+
#endif
363+
#endif
364+
351365
ENUM_LANGOPT(Float16ExcessPrecision, ExcessPrecisionKind, 2, FPP_Standard, "Intermediate truncation behavior for Float16 arithmetic")
352366
ENUM_LANGOPT(BFloat16ExcessPrecision, ExcessPrecisionKind, 2, FPP_Standard, "Intermediate truncation behavior for BFloat16 arithmetic")
353367
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")

clang/include/clang/Basic/LangOptions.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,23 @@ class LangOptionsBase {
7676
using RoundingMode = llvm::RoundingMode;
7777
using CFBranchLabelSchemeKind = clang::CFBranchLabelSchemeKind;
7878

79+
LangOptionsBase() = default;
80+
81+
#if defined(__clang__) && defined( __has_warning)
82+
#if __has_warning("-Wpreferred-type-bitfield-enum-conversion")
83+
// FIXME: Remove this once the warning is fixed, https://llvm.org/PR137600
84+
#pragma clang diagnostic push
85+
#pragma clang diagnostic ignored "-Wpreferred-type-bitfield-enum-conversion"
86+
#endif
87+
#endif
88+
LangOptionsBase(const LangOptionsBase&) = default;
89+
LangOptionsBase& operator=(const LangOptionsBase&) = default;
90+
#if defined(__clang__) && defined( __has_warning)
91+
#if __has_warning("-Wpreferred-type-bitfield-enum-conversion")
92+
#pragma clang diagnostic pop
93+
#endif
94+
#endif
95+
7996
enum GCMode { NonGC, GCOnly, HybridGC };
8097
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
8198

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
14831483
break;
14841484
case OwnershipAttr::Returns:
14851485
if (AL.getNumArgs() > 2) {
1486-
S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1486+
S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 2;
14871487
return;
14881488
}
14891489
break;
@@ -4907,6 +4907,20 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
49074907
D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
49084908
}
49094909

4910+
static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4911+
// This only applies to fields and variable declarations which have an array
4912+
// type.
4913+
QualType QT = cast<ValueDecl>(D)->getType();
4914+
if (!QT->isArrayType() ||
4915+
!QT->getBaseElementTypeUnsafe()->isAnyCharacterType()) {
4916+
S.Diag(D->getBeginLoc(), diag::warn_attribute_non_character_array)
4917+
<< AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
4918+
return;
4919+
}
4920+
4921+
D->addAttr(::new (S.Context) NonStringAttr(S.Context, AL));
4922+
}
4923+
49104924
static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
49114925
D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
49124926
}
@@ -7144,6 +7158,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
71447158
case ParsedAttr::AT_Mode:
71457159
handleModeAttr(S, D, AL);
71467160
break;
7161+
case ParsedAttr::AT_NonString:
7162+
handleNonStringAttr(S, D, AL);
7163+
break;
71477164
case ParsedAttr::AT_NonNull:
71487165
if (auto *PVD = dyn_cast<ParmVarDecl>(D))
71497166
handleNonNullAttrParameter(S, PVD, AL);

0 commit comments

Comments
 (0)