Skip to content

Commit 9711fab

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:f50d3582b4844b86ad86372028e44b52c560ec7d into amd-gfx:75f020611ed6
Local branch amd-gfx 75f0206 Merged main:8a8ef1cacfcd7745d2b6ad00431e6fa9ab9a2fb4 into amd-gfx:c6ac0bd36762 Remote branch main f50d358 [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (llvm#84127)
2 parents 75f0206 + f50d358 commit 9711fab

File tree

75 files changed

+1382
-695
lines changed

Some content is hidden

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

75 files changed

+1382
-695
lines changed

.github/workflows/llvm-project-tests.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ jobs:
118118
else
119119
builddir="$(pwd)"/build
120120
fi
121+
if [ "${{ runner.os }}" == "macOS" ]; then
122+
# Workaround test failure on some lld tests on MacOS
123+
# https://github.com/llvm/llvm-project/issues/81967
124+
extra_cmake_args="-DLLVM_DISABLE_ASSEMBLY_FILES=ON"
125+
fi
121126
echo "llvm-builddir=$builddir" >> "$GITHUB_OUTPUT"
122127
cmake -G Ninja \
123128
-B "$builddir" \

clang/docs/ReleaseNotes.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ Improvements to Clang's diagnostics
237237
- Clang now diagnoses lambda function expressions being implicitly cast to boolean values, under ``-Wpointer-bool-conversion``.
238238
Fixes #GH82512.
239239

240+
- Clang now provides improved warnings for the ``cleanup`` attribute to detect misuse scenarios,
241+
such as attempting to call ``free`` on an unallocated object. Fixes
242+
`#79443 <https://github.com/llvm/llvm-project/issues/79443>`_.
243+
240244
Improvements to Clang's time-trace
241245
----------------------------------
242246

@@ -274,6 +278,13 @@ Bug Fixes in This Version
274278
- Clang now correctly generates overloads for bit-precise integer types for
275279
builtin operators in C++. Fixes #GH82998.
276280

281+
- When performing mixed arithmetic between ``_Complex`` floating-point types and integers,
282+
Clang now correctly promotes the integer to its corresponding real floating-point
283+
type only rather than to the complex type (e.g. ``_Complex float / int`` is now evaluated
284+
as ``_Complex float / float`` rather than ``_Complex float / _Complex float``), as mandated
285+
by the C standard. This significantly improves codegen of `*` and `/` especially.
286+
Fixes (`#31205 <https://github.com/llvm/llvm-project/issues/31205>`_).
287+
277288
Bug Fixes to Compiler Builtins
278289
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
279290

@@ -362,6 +373,9 @@ Bug Fixes to C++ Support
362373
and (`#74494 <https://github.com/llvm/llvm-project/issues/74494>`_)
363374
- Allow access to a public template alias declaration that refers to friend's
364375
private nested type. (#GH25708).
376+
- Fixed a crash in constant evaluation when trying to access a
377+
captured ``this`` pointer in a lambda with an explicit object parameter.
378+
Fixes (#GH80997)
365379

366380
Bug Fixes to AST Handling
367381
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,14 +2152,15 @@ class Sema final {
21522152

21532153
bool IsLayoutCompatible(QualType T1, QualType T2) const;
21542154

2155+
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
2156+
const FunctionProtoType *Proto);
2157+
21552158
private:
21562159
void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
21572160
const ArraySubscriptExpr *ASE = nullptr,
21582161
bool AllowOnePastEnd = true, bool IndexNegated = false);
21592162
void CheckArrayAccess(const Expr *E);
21602163

2161-
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
2162-
const FunctionProtoType *Proto);
21632164
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
21642165
ArrayRef<const Expr *> Args);
21652166
bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,

clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ class CallDescription {
4141
/// - We also accept calls where the number of arguments or parameters is
4242
/// greater than the specified value.
4343
/// For the exact heuristics, see CheckerContext::isCLibraryFunction().
44-
/// (This mode only matches functions that are declared either directly
45-
/// within a TU or in the namespace `std`.)
44+
/// Note that functions whose declaration context is not a TU (e.g.
45+
/// methods, functions in namespaces) are not accepted as C library
46+
/// functions.
47+
/// FIXME: If I understand it correctly, this discards calls where C++ code
48+
/// refers a C library function through the namespace `std::` via headers
49+
/// like <cstdlib>.
4650
CLibrary,
4751

4852
/// Matches "simple" functions that are not methods. (Static methods are

clang/lib/AST/ExprConstant.cpp

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8517,6 +8517,53 @@ class LValueExprEvaluator
85178517
};
85188518
} // end anonymous namespace
85198519

8520+
/// Get an lvalue to a field of a lambda's closure type.
8521+
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result,
8522+
const CXXMethodDecl *MD, const FieldDecl *FD,
8523+
bool LValueToRValueConversion) {
8524+
// Static lambda function call operators can't have captures. We already
8525+
// diagnosed this, so bail out here.
8526+
if (MD->isStatic()) {
8527+
assert(Info.CurrentCall->This == nullptr &&
8528+
"This should not be set for a static call operator");
8529+
return false;
8530+
}
8531+
8532+
// Start with 'Result' referring to the complete closure object...
8533+
if (MD->isExplicitObjectMemberFunction()) {
8534+
// Self may be passed by reference or by value.
8535+
const ParmVarDecl *Self = MD->getParamDecl(0);
8536+
if (Self->getType()->isReferenceType()) {
8537+
APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8538+
Result.setFrom(Info.Ctx, *RefValue);
8539+
} else {
8540+
const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8541+
CallStackFrame *Frame =
8542+
Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8543+
.first;
8544+
unsigned Version = Info.CurrentCall->Arguments.Version;
8545+
Result.set({VD, Frame->Index, Version});
8546+
}
8547+
} else
8548+
Result = *Info.CurrentCall->This;
8549+
8550+
// ... then update it to refer to the field of the closure object
8551+
// that represents the capture.
8552+
if (!HandleLValueMember(Info, E, Result, FD))
8553+
return false;
8554+
8555+
// And if the field is of reference type (or if we captured '*this' by
8556+
// reference), update 'Result' to refer to what
8557+
// the field refers to.
8558+
if (LValueToRValueConversion) {
8559+
APValue RVal;
8560+
if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result, RVal))
8561+
return false;
8562+
Result.setFrom(Info.Ctx, RVal);
8563+
}
8564+
return true;
8565+
}
8566+
85208567
/// Evaluate an expression as an lvalue. This can be legitimately called on
85218568
/// expressions which are not glvalues, in three cases:
85228569
/// * function designators in C, and
@@ -8561,37 +8608,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
85618608

85628609
if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
85638610
const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8564-
8565-
// Static lambda function call operators can't have captures. We already
8566-
// diagnosed this, so bail out here.
8567-
if (MD->isStatic()) {
8568-
assert(Info.CurrentCall->This == nullptr &&
8569-
"This should not be set for a static call operator");
8570-
return false;
8571-
}
8572-
8573-
// Start with 'Result' referring to the complete closure object...
8574-
if (MD->isExplicitObjectMemberFunction()) {
8575-
APValue *RefValue =
8576-
Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0));
8577-
Result.setFrom(Info.Ctx, *RefValue);
8578-
} else
8579-
Result = *Info.CurrentCall->This;
8580-
8581-
// ... then update it to refer to the field of the closure object
8582-
// that represents the capture.
8583-
if (!HandleLValueMember(Info, E, Result, FD))
8584-
return false;
8585-
// And if the field is of reference type, update 'Result' to refer to what
8586-
// the field refers to.
8587-
if (FD->getType()->isReferenceType()) {
8588-
APValue RVal;
8589-
if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result,
8590-
RVal))
8591-
return false;
8592-
Result.setFrom(Info.Ctx, RVal);
8593-
}
8594-
return true;
8611+
return HandleLambdaCapture(Info, E, Result, MD, FD,
8612+
FD->getType()->isReferenceType());
85958613
}
85968614
}
85978615

@@ -9069,45 +9087,46 @@ class PointerExprEvaluator
90699087
return Error(E);
90709088
}
90719089
bool VisitCXXThisExpr(const CXXThisExpr *E) {
9072-
// Can't look at 'this' when checking a potential constant expression.
9073-
if (Info.checkingPotentialConstantExpression())
9074-
return false;
9075-
if (!Info.CurrentCall->This) {
9090+
auto DiagnoseInvalidUseOfThis = [&] {
90769091
if (Info.getLangOpts().CPlusPlus11)
90779092
Info.FFDiag(E, diag::note_constexpr_this) << E->isImplicit();
90789093
else
90799094
Info.FFDiag(E);
9095+
};
9096+
9097+
// Can't look at 'this' when checking a potential constant expression.
9098+
if (Info.checkingPotentialConstantExpression())
90809099
return false;
9100+
9101+
bool IsExplicitLambda =
9102+
isLambdaCallWithExplicitObjectParameter(Info.CurrentCall->Callee);
9103+
if (!IsExplicitLambda) {
9104+
if (!Info.CurrentCall->This) {
9105+
DiagnoseInvalidUseOfThis();
9106+
return false;
9107+
}
9108+
9109+
Result = *Info.CurrentCall->This;
90819110
}
9082-
Result = *Info.CurrentCall->This;
90839111

90849112
if (isLambdaCallOperator(Info.CurrentCall->Callee)) {
90859113
// Ensure we actually have captured 'this'. If something was wrong with
90869114
// 'this' capture, the error would have been previously reported.
90879115
// Otherwise we can be inside of a default initialization of an object
90889116
// declared by lambda's body, so no need to return false.
9089-
if (!Info.CurrentCall->LambdaThisCaptureField)
9090-
return true;
9091-
9092-
// If we have captured 'this', the 'this' expression refers
9093-
// to the enclosing '*this' object (either by value or reference) which is
9094-
// either copied into the closure object's field that represents the
9095-
// '*this' or refers to '*this'.
9096-
// Update 'Result' to refer to the data member/field of the closure object
9097-
// that represents the '*this' capture.
9098-
if (!HandleLValueMember(Info, E, Result,
9099-
Info.CurrentCall->LambdaThisCaptureField))
9100-
return false;
9101-
// If we captured '*this' by reference, replace the field with its referent.
9102-
if (Info.CurrentCall->LambdaThisCaptureField->getType()
9103-
->isPointerType()) {
9104-
APValue RVal;
9105-
if (!handleLValueToRValueConversion(Info, E, E->getType(), Result,
9106-
RVal))
9117+
if (!Info.CurrentCall->LambdaThisCaptureField) {
9118+
if (IsExplicitLambda && !Info.CurrentCall->This) {
9119+
DiagnoseInvalidUseOfThis();
91079120
return false;
9121+
}
91089122

9109-
Result.setFrom(Info.Ctx, RVal);
9123+
return true;
91109124
}
9125+
9126+
const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9127+
return HandleLambdaCapture(
9128+
Info, E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9129+
Info.CurrentCall->LambdaThisCaptureField->getType()->isPointerType());
91119130
}
91129131
return true;
91139132
}

clang/lib/Basic/Module.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,9 @@ bool Module::directlyUses(const Module *Requested) {
301301
if (Requested->isSubModuleOf(Use))
302302
return true;
303303

304-
// Anyone is allowed to use our builtin stdarg.h and stddef.h and their
305-
// accompanying modules.
306-
if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" ||
307-
Requested->getTopLevelModuleName() == "_Builtin_stddef")
304+
// Anyone is allowed to use our builtin stddef.h and its accompanying modules.
305+
if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
306+
Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
308307
return true;
309308

310309
if (NoUndeclaredIncludes)

clang/lib/Headers/__stddef_null.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(NULL) || !__has_feature(modules)
10+
#if !defined(NULL) || !__building_module(_Builtin_stddef)
1111

1212
/* linux/stddef.h will define NULL to 0. glibc (and other) headers then define
1313
* __need_NULL and rely on stddef.h to redefine NULL to the correct value again.

clang/lib/Headers/__stddef_nullptr_t.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#ifndef _NULLPTR_T
10+
/*
11+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
12+
* and needs to behave as if it was textual.
13+
*/
14+
#if !defined(_NULLPTR_T) || \
15+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1116
#define _NULLPTR_T
1217

1318
#ifdef __cplusplus

clang/lib/Headers/__stddef_offsetof.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#ifndef offsetof
10+
/*
11+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
12+
* and needs to behave as if it was textual.
13+
*/
14+
#if !defined(offsetof) || \
15+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1116
#define offsetof(t, d) __builtin_offsetof(t, d)
1217
#endif

clang/lib/Headers/__stddef_ptrdiff_t.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#ifndef _PTRDIFF_T
10+
/*
11+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
12+
* and needs to behave as if it was textual.
13+
*/
14+
#if !defined(_PTRDIFF_T) || \
15+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1116
#define _PTRDIFF_T
1217

1318
typedef __PTRDIFF_TYPE__ ptrdiff_t;

clang/lib/Headers/__stddef_rsize_t.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#ifndef _RSIZE_T
10+
/*
11+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
12+
* and needs to behave as if it was textual.
13+
*/
14+
#if !defined(_RSIZE_T) || \
15+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1116
#define _RSIZE_T
1217

1318
typedef __SIZE_TYPE__ rsize_t;

clang/lib/Headers/__stddef_size_t.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#ifndef _SIZE_T
10+
/*
11+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
12+
* and needs to behave as if it was textual.
13+
*/
14+
#if !defined(_SIZE_T) || \
15+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1116
#define _SIZE_T
1217

1318
typedef __SIZE_TYPE__ size_t;

clang/lib/Headers/__stddef_unreachable.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#ifndef unreachable
10+
/*
11+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
12+
* and needs to behave as if it was textual.
13+
*/
14+
#if !defined(unreachable) || \
15+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1116
#define unreachable() __builtin_unreachable()
1217
#endif

clang/lib/Headers/__stddef_wchar_t.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99

1010
#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
1111

12-
#ifndef _WCHAR_T
12+
/*
13+
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
14+
* and needs to behave as if it was textual.
15+
*/
16+
#if !defined(_WCHAR_T) || \
17+
(__has_feature(modules) && !__building_module(_Builtin_stddef))
1318
#define _WCHAR_T
1419

1520
#ifdef _MSC_EXTENSIONS

0 commit comments

Comments
 (0)