Skip to content

Commit a4a2a78

Browse files
authored
Merge branch 'main' into lldb-dap-module-events
2 parents c01964e + a230bb0 commit a4a2a78

File tree

159 files changed

+4377
-6840
lines changed

Some content is hidden

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

159 files changed

+4377
-6840
lines changed

bolt/test/runtime/X86/fdata-escape-chars.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ define internal void @static_symb_backslash_b() #0 {
8282
; INSTR_CHECK: Binary Function "main"
8383
; INSTR_CHECK: Exec Count : 1
8484
; INSTR_CHECK: {{([[:xdigit:]]+)}}: callq "symb whitespace" # Count: 1
85-
; INSTR_CHECK: {{([[:xdigit:]]+)}}: callq "symb backslash\" # Count: 2
85+
; INSTR_CHECK: {{([[:xdigit:]]+)}}: callq "symb backslash\\" # Count: 2
8686
; INSTR_CHECK: Binary Function "static symb backslash\/1(*2)"
8787
; INSTR_CHECK: Exec Count : 1
8888
; INSTR_CHECK: {{([[:xdigit:]]+)}}: callq "symb whitespace" # Count: 1

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,9 @@ Improvements to Clang's diagnostics
512512
- Several compatibility diagnostics that were incorrectly being grouped under
513513
``-Wpre-c++20-compat`` are now part of ``-Wc++20-compat``. (#GH138775)
514514

515+
- Improved the ``-Wtautological-overlap-compare`` diagnostics to warn about overlapping and non-overlapping ranges involving character literals and floating-point literals.
516+
The warning message for non-overlapping cases has also been improved (#GH13473).
517+
515518
Improvements to Clang's time-trace
516519
----------------------------------
517520

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
499499
/// The name of a file to use with \c .secure_log_unique directives.
500500
std::string AsSecureLogFile;
501501

502+
/// A list of functions that are replacable by the loader.
503+
std::vector<std::string> LoaderReplaceableFunctionNames;
504+
502505
public:
503506
// Define accessors/mutators for code generation options of enumeration type.
504507
#define CODEGENOPT(Name, Bits, Default)
@@ -571,6 +574,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
571574
/// Reset all of the options that are not considered when building a
572575
/// module.
573576
void resetNonModularOptions(StringRef ModuleFormat);
577+
578+
// Is the given function name one of the functions that can be replaced by the
579+
// loader?
580+
bool isLoaderReplaceableFunctionName(StringRef FuncName) const {
581+
return llvm::is_contained(LoaderReplaceableFunctionNames, FuncName);
582+
}
574583
};
575584

576585
} // end namespace clang

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10531,7 +10531,7 @@ def warn_tautological_negation_or_compare: Warning<
1053110531
"'||' of a value and its negation always evaluates to true">,
1053210532
InGroup<TautologicalNegationCompare>, DefaultIgnore;
1053310533
def warn_tautological_overlap_comparison : Warning<
10534-
"overlapping comparisons always evaluate to %select{false|true}0">,
10534+
"%select{non-|}0overlapping comparisons always evaluate to %select{false|true}0">,
1053510535
InGroup<TautologicalOverlapCompare>, DefaultIgnore;
1053610536
def warn_depr_array_comparison : Warning<
1053710537
"comparison between two arrays is deprecated; "

clang/include/clang/Driver/Options.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7826,6 +7826,9 @@ def import_call_optimization : Flag<["-"], "import-call-optimization">,
78267826
"by the Windows kernel to enable import call optimization">,
78277827
MarshallingInfoFlag<CodeGenOpts<"ImportCallOptimization">>;
78287828

7829+
def replaceable_function: Joined<["-"], "loader-replaceable-function=">,
7830+
MarshallingInfoStringVector<CodeGenOpts<"LoaderReplaceableFunctionNames">>;
7831+
78297832
} // let Visibility = [CC1Option]
78307833

78317834
//===----------------------------------------------------------------------===//
@@ -9088,6 +9091,10 @@ def _SLASH_Gregcall : CLFlag<"Gregcall">,
90889091
def _SLASH_Gregcall4 : CLFlag<"Gregcall4">,
90899092
HelpText<"Set __regcall4 as a default calling convention to respect __regcall ABI v.4">;
90909093

9094+
def _SLASH_funcoverride : CLCompileJoined<"funcoverride:">,
9095+
HelpText<"Mark <function> as being replaceable by the Windows kernel loader">,
9096+
MetaVarName<"<function>">;
9097+
90919098
// GNU Driver aliases
90929099

90939100
def : Separate<["-"], "Xmicrosoft-visualc-tools-root">, Alias<_SLASH_vctoolsdir>;

clang/lib/Analysis/CFG.cpp

Lines changed: 112 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "clang/Basic/LangOptions.h"
3737
#include "clang/Basic/SourceLocation.h"
3838
#include "clang/Basic/Specifiers.h"
39+
#include "llvm/ADT/APFloat.h"
3940
#include "llvm/ADT/APInt.h"
4041
#include "llvm/ADT/APSInt.h"
4142
#include "llvm/ADT/ArrayRef.h"
@@ -70,19 +71,19 @@ static SourceLocation GetEndLoc(Decl *D) {
7071
return D->getLocation();
7172
}
7273

73-
/// Returns true on constant values based around a single IntegerLiteral.
74-
/// Allow for use of parentheses, integer casts, and negative signs.
75-
/// FIXME: it would be good to unify this function with
76-
/// getIntegerLiteralSubexpressionValue at some point given the similarity
77-
/// between the functions.
74+
/// Returns true on constant values based around a single IntegerLiteral,
75+
/// CharacterLiteral, or FloatingLiteral. Allow for use of parentheses, integer
76+
/// casts, and negative signs.
7877

79-
static bool IsIntegerLiteralConstantExpr(const Expr *E) {
78+
static bool IsLiteralConstantExpr(const Expr *E) {
8079
// Allow parentheses
8180
E = E->IgnoreParens();
8281

83-
// Allow conversions to different integer kind.
82+
// Allow conversions to different integer kind, and integer to floating point
83+
// (to account for float comparing with int).
8484
if (const auto *CE = dyn_cast<CastExpr>(E)) {
85-
if (CE->getCastKind() != CK_IntegralCast)
85+
if (CE->getCastKind() != CK_IntegralCast &&
86+
CE->getCastKind() != CK_IntegralToFloating)
8687
return false;
8788
E = CE->getSubExpr();
8889
}
@@ -93,16 +94,15 @@ static bool IsIntegerLiteralConstantExpr(const Expr *E) {
9394
return false;
9495
E = UO->getSubExpr();
9596
}
96-
97-
return isa<IntegerLiteral>(E);
97+
return isa<IntegerLiteral, CharacterLiteral, FloatingLiteral>(E);
9898
}
9999

100100
/// Helper for tryNormalizeBinaryOperator. Attempts to extract an IntegerLiteral
101-
/// constant expression or EnumConstantDecl from the given Expr. If it fails,
102-
/// returns nullptr.
103-
static const Expr *tryTransformToIntOrEnumConstant(const Expr *E) {
101+
/// FloatingLiteral, CharacterLiteral or EnumConstantDecl from the given Expr.
102+
/// If it fails, returns nullptr.
103+
static const Expr *tryTransformToLiteralConstant(const Expr *E) {
104104
E = E->IgnoreParens();
105-
if (IsIntegerLiteralConstantExpr(E))
105+
if (IsLiteralConstantExpr(E))
106106
return E;
107107
if (auto *DR = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
108108
return isa<EnumConstantDecl>(DR->getDecl()) ? DR : nullptr;
@@ -119,7 +119,7 @@ tryNormalizeBinaryOperator(const BinaryOperator *B) {
119119
BinaryOperatorKind Op = B->getOpcode();
120120

121121
const Expr *MaybeDecl = B->getLHS();
122-
const Expr *Constant = tryTransformToIntOrEnumConstant(B->getRHS());
122+
const Expr *Constant = tryTransformToLiteralConstant(B->getRHS());
123123
// Expr looked like `0 == Foo` instead of `Foo == 0`
124124
if (Constant == nullptr) {
125125
// Flip the operator
@@ -133,7 +133,7 @@ tryNormalizeBinaryOperator(const BinaryOperator *B) {
133133
Op = BO_GE;
134134

135135
MaybeDecl = B->getRHS();
136-
Constant = tryTransformToIntOrEnumConstant(B->getLHS());
136+
Constant = tryTransformToLiteralConstant(B->getLHS());
137137
}
138138

139139
return std::make_tuple(MaybeDecl, Op, Constant);
@@ -1082,10 +1082,10 @@ class CFGBuilder {
10821082
return std::nullopt;
10831083
}
10841084

1085+
template <typename APFloatOrInt>
10851086
TryResult analyzeLogicOperatorCondition(BinaryOperatorKind Relation,
1086-
const llvm::APSInt &Value1,
1087-
const llvm::APSInt &Value2) {
1088-
assert(Value1.isSigned() == Value2.isSigned());
1087+
const APFloatOrInt &Value1,
1088+
const APFloatOrInt &Value2) {
10891089
switch (Relation) {
10901090
default:
10911091
return TryResult();
@@ -1170,82 +1170,120 @@ class CFGBuilder {
11701170
if (!areExprTypesCompatible(NumExpr1, NumExpr2))
11711171
return {};
11721172

1173+
// Check that the two expressions are of the same type.
11731174
Expr::EvalResult L1Result, L2Result;
1174-
if (!NumExpr1->EvaluateAsInt(L1Result, *Context) ||
1175-
!NumExpr2->EvaluateAsInt(L2Result, *Context))
1176-
return {};
1177-
1178-
llvm::APSInt L1 = L1Result.Val.getInt();
1179-
llvm::APSInt L2 = L2Result.Val.getInt();
1180-
1181-
// Can't compare signed with unsigned or with different bit width.
1182-
if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth())
1175+
if (!NumExpr1->EvaluateAsRValue(L1Result, *Context) ||
1176+
!NumExpr2->EvaluateAsRValue(L2Result, *Context))
11831177
return {};
11841178

1185-
// Values that will be used to determine if result of logical
1186-
// operator is always true/false
1187-
const llvm::APSInt Values[] = {
1188-
// Value less than both Value1 and Value2
1189-
llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()),
1190-
// L1
1191-
L1,
1192-
// Value between Value1 and Value2
1193-
((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1),
1194-
L1.isUnsigned()),
1195-
// L2
1196-
L2,
1197-
// Value greater than both Value1 and Value2
1198-
llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()),
1199-
};
1200-
1201-
// Check whether expression is always true/false by evaluating the following
1179+
// Check whether expression is always true/false by evaluating the
1180+
// following
12021181
// * variable x is less than the smallest literal.
12031182
// * variable x is equal to the smallest literal.
12041183
// * Variable x is between smallest and largest literal.
12051184
// * Variable x is equal to the largest literal.
12061185
// * Variable x is greater than largest literal.
1207-
bool AlwaysTrue = true, AlwaysFalse = true;
1208-
// Track value of both subexpressions. If either side is always
1209-
// true/false, another warning should have already been emitted.
1210-
bool LHSAlwaysTrue = true, LHSAlwaysFalse = true;
1211-
bool RHSAlwaysTrue = true, RHSAlwaysFalse = true;
1212-
for (const llvm::APSInt &Value : Values) {
1213-
TryResult Res1, Res2;
1214-
Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
1215-
Res2 = analyzeLogicOperatorCondition(BO2, Value, L2);
1216-
1217-
if (!Res1.isKnown() || !Res2.isKnown())
1218-
return {};
1186+
// This isn't technically correct, as it doesn't take into account the
1187+
// possibility that the variable could be NaN. However, this is a very rare
1188+
// case.
1189+
auto AnalyzeConditions = [&](const auto &Values,
1190+
const BinaryOperatorKind *BO1,
1191+
const BinaryOperatorKind *BO2) -> TryResult {
1192+
bool AlwaysTrue = true, AlwaysFalse = true;
1193+
// Track value of both subexpressions. If either side is always
1194+
// true/false, another warning should have already been emitted.
1195+
bool LHSAlwaysTrue = true, LHSAlwaysFalse = true;
1196+
bool RHSAlwaysTrue = true, RHSAlwaysFalse = true;
1197+
1198+
for (const auto &Value : Values) {
1199+
TryResult Res1 =
1200+
analyzeLogicOperatorCondition(*BO1, Value, Values[1] /* L1 */);
1201+
TryResult Res2 =
1202+
analyzeLogicOperatorCondition(*BO2, Value, Values[3] /* L2 */);
1203+
1204+
if (!Res1.isKnown() || !Res2.isKnown())
1205+
return {};
1206+
1207+
const bool IsAnd = B->getOpcode() == BO_LAnd;
1208+
const bool Combine = IsAnd ? (Res1.isTrue() && Res2.isTrue())
1209+
: (Res1.isTrue() || Res2.isTrue());
1210+
1211+
AlwaysTrue &= Combine;
1212+
AlwaysFalse &= !Combine;
1213+
1214+
LHSAlwaysTrue &= Res1.isTrue();
1215+
LHSAlwaysFalse &= Res1.isFalse();
1216+
RHSAlwaysTrue &= Res2.isTrue();
1217+
RHSAlwaysFalse &= Res2.isFalse();
1218+
}
12191219

1220-
if (B->getOpcode() == BO_LAnd) {
1221-
AlwaysTrue &= (Res1.isTrue() && Res2.isTrue());
1222-
AlwaysFalse &= !(Res1.isTrue() && Res2.isTrue());
1223-
} else {
1224-
AlwaysTrue &= (Res1.isTrue() || Res2.isTrue());
1225-
AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue());
1220+
if (AlwaysTrue || AlwaysFalse) {
1221+
if (!LHSAlwaysTrue && !LHSAlwaysFalse && !RHSAlwaysTrue &&
1222+
!RHSAlwaysFalse && BuildOpts.Observer) {
1223+
BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
1224+
}
1225+
return TryResult(AlwaysTrue);
12261226
}
1227+
return {};
1228+
};
12271229

1228-
LHSAlwaysTrue &= Res1.isTrue();
1229-
LHSAlwaysFalse &= Res1.isFalse();
1230-
RHSAlwaysTrue &= Res2.isTrue();
1231-
RHSAlwaysFalse &= Res2.isFalse();
1230+
// Handle integer comparison.
1231+
if (L1Result.Val.getKind() == APValue::Int &&
1232+
L2Result.Val.getKind() == APValue::Int) {
1233+
llvm::APSInt L1 = L1Result.Val.getInt();
1234+
llvm::APSInt L2 = L2Result.Val.getInt();
1235+
1236+
// Can't compare signed with unsigned or with different bit width.
1237+
if (L1.isSigned() != L2.isSigned() ||
1238+
L1.getBitWidth() != L2.getBitWidth())
1239+
return {};
1240+
1241+
// Values that will be used to determine if result of logical
1242+
// operator is always true/false
1243+
const llvm::APSInt Values[] = {
1244+
// Value less than both Value1 and Value2
1245+
llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()),
1246+
// L1
1247+
L1,
1248+
// Value between Value1 and Value2
1249+
((L1 < L2) ? L1 : L2) +
1250+
llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1), L1.isUnsigned()),
1251+
// L2
1252+
L2,
1253+
// Value greater than both Value1 and Value2
1254+
llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()),
1255+
};
1256+
1257+
return AnalyzeConditions(Values, &BO1, &BO2);
12321258
}
12331259

1234-
if (AlwaysTrue || AlwaysFalse) {
1235-
if (!LHSAlwaysTrue && !LHSAlwaysFalse && !RHSAlwaysTrue &&
1236-
!RHSAlwaysFalse && BuildOpts.Observer)
1237-
BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
1238-
return TryResult(AlwaysTrue);
1260+
// Handle float comparison.
1261+
if (L1Result.Val.getKind() == APValue::Float &&
1262+
L2Result.Val.getKind() == APValue::Float) {
1263+
llvm::APFloat L1 = L1Result.Val.getFloat();
1264+
llvm::APFloat L2 = L2Result.Val.getFloat();
1265+
llvm::APFloat MidValue = L1;
1266+
MidValue.add(L2, llvm::APFloat::rmNearestTiesToEven);
1267+
MidValue.divide(llvm::APFloat(MidValue.getSemantics(), "2.0"),
1268+
llvm::APFloat::rmNearestTiesToEven);
1269+
1270+
const llvm::APFloat Values[] = {
1271+
llvm::APFloat::getSmallest(L1.getSemantics(), true), L1, MidValue, L2,
1272+
llvm::APFloat::getLargest(L2.getSemantics(), false),
1273+
};
1274+
1275+
return AnalyzeConditions(Values, &BO1, &BO2);
12391276
}
1277+
12401278
return {};
12411279
}
12421280

12431281
/// A bitwise-or with a non-zero constant always evaluates to true.
12441282
TryResult checkIncorrectBitwiseOrOperator(const BinaryOperator *B) {
12451283
const Expr *LHSConstant =
1246-
tryTransformToIntOrEnumConstant(B->getLHS()->IgnoreParenImpCasts());
1284+
tryTransformToLiteralConstant(B->getLHS()->IgnoreParenImpCasts());
12471285
const Expr *RHSConstant =
1248-
tryTransformToIntOrEnumConstant(B->getRHS()->IgnoreParenImpCasts());
1286+
tryTransformToLiteralConstant(B->getRHS()->IgnoreParenImpCasts());
12491287

12501288
if ((LHSConstant && RHSConstant) || (!LHSConstant && !RHSConstant))
12511289
return {};

clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,10 @@ class OpenACCClauseCIREmitter final
229229
operation.addNumWorkersOperand(builder.getContext(),
230230
createIntExpr(clause.getIntExpr()),
231231
lastDeviceTypeValues);
232-
} else if constexpr (isOneOfTypes<OpTy, mlir::acc::SerialOp>) {
233-
llvm_unreachable("num_workers not valid on serial");
232+
} else if constexpr (isCombinedType<OpTy>) {
233+
applyToComputeOp(clause);
234234
} else {
235-
// TODO: When we've implemented this for everything, switch this to an
236-
// unreachable. Combined constructs remain.
237-
return clauseNotImplemented(clause);
235+
llvm_unreachable("Unknown construct kind in VisitNumGangsClause");
238236
}
239237
}
240238

@@ -244,12 +242,10 @@ class OpenACCClauseCIREmitter final
244242
operation.addVectorLengthOperand(builder.getContext(),
245243
createIntExpr(clause.getIntExpr()),
246244
lastDeviceTypeValues);
247-
} else if constexpr (isOneOfTypes<OpTy, mlir::acc::SerialOp>) {
248-
llvm_unreachable("vector_length not valid on serial");
245+
} else if constexpr (isCombinedType<OpTy>) {
246+
applyToComputeOp(clause);
249247
} else {
250-
// TODO: When we've implemented this for everything, switch this to an
251-
// unreachable. Combined constructs remain.
252-
return clauseNotImplemented(clause);
248+
llvm_unreachable("Unknown construct kind in VisitVectorLengthClause");
253249
}
254250
}
255251

@@ -339,10 +335,10 @@ class OpenACCClauseCIREmitter final
339335

340336
operation.addNumGangsOperands(builder.getContext(), values,
341337
lastDeviceTypeValues);
338+
} else if constexpr (isCombinedType<OpTy>) {
339+
applyToComputeOp(clause);
342340
} else {
343-
// TODO: When we've implemented this for everything, switch this to an
344-
// unreachable. Combined constructs remain.
345-
return clauseNotImplemented(clause);
341+
llvm_unreachable("Unknown construct kind in VisitNumGangsClause");
346342
}
347343
}
348344

clang/lib/CodeGen/CGCall.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,6 +2641,10 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
26412641
GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
26422642
}
26432643

2644+
// Mark functions that are replaceable by the loader.
2645+
if (CodeGenOpts.isLoaderReplaceableFunctionName(Name))
2646+
FuncAttrs.addAttribute("loader-replaceable");
2647+
26442648
// Collect attributes from arguments and return values.
26452649
ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI);
26462650

0 commit comments

Comments
 (0)