Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a1476d8
[NFC][X86] shouldUseHorizontalOp - constify SelectionDAG argument (#1…
RKSimon May 17, 2026
f94a690
[Passes] Use consistent naming for printer passes (#198144)
boomanaiden154 May 17, 2026
47e142b
[AArch64] Fix handling of x29/x30 in inline assembly clobbers (#167783)
lalinsky May 17, 2026
3a2876d
[mlir][SPIR-V] Fix math.powf lowering for non-integer exponents (#197…
aobolensk May 17, 2026
598acfb
[sanitizer][test] Fix coverage-module-unloaded.cpp etc. on Solaris (#…
rorth May 17, 2026
0e92b55
[sanitizer_common] Fix sanitizer_platform_limits_solaris.cpp compilat…
rorth May 17, 2026
c497efb
[InstCombine] Convert logical and/or with trunc nuw to i1 into bitwis…
andjo403 May 17, 2026
df90525
[JTS] Readd assertion
boomanaiden154 May 17, 2026
856f7d4
[LV] Extract helper to simplify phi removal in connectEpiVectorL (NFC…
fhahn May 17, 2026
46c1fa8
[VPlan] Use ResumeForEpilogue to get epilogue vector trip count (NFC)…
fhahn May 17, 2026
c5c8e91
[ICP] Update comment about duplicate values in VP MD
boomanaiden154 May 17, 2026
5f2bedc
Add clang warning if fp exception functions are called without approp…
maarcosrmz May 17, 2026
3a1206a
[LV] Add find-last-iv test with blend (NFC). (#198214)
fhahn May 17, 2026
6a14487
[NewPM] Add newpm port for AArch64LowerHomogeneousPrologEpilog (#197606)
nigham May 17, 2026
938211b
[LV] Move isMoreProfitable to LoopVectorizationPlanner.cpp (NFC). (#1…
fhahn May 17, 2026
3d3f4be
[compiler-rt] Fix StackDepot benchmark thread barrier (#197633)
mechakotik May 17, 2026
8f740a3
[clang-tidy] Fix crash in misc-static-initialization-cycle (#198155)
zeyi2 May 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class VarUseCollector : public DynamicRecursiveASTVisitor {
}
bool TraverseAttr(Attr *At) override { return true; }
bool TraverseDecl(Decl *D) override {
if (DC && DC->containsDecl(D))
if (D && DC && DC->containsDecl(D))
return DynamicRecursiveASTVisitor::TraverseDecl(D);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ int f1() {
int S::A = f1();
}

namespace catch_all_handler {
void f() {
try {
} catch (...) {
}
}
} // catch_all_handler

namespace recursive_calls {
int f2();
int f1() {
Expand Down
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ Improvements to Clang's diagnostics

- Added ``-Wattribute-alias`` to diagnose type mismatches between an alias and its aliased function. (#GH195550)

- Added warnings for floating-point exception function calls (fenv.h) without enabling
floating-point exception behavior via the appropriate flags or pragmas. (#GH128239)

Improvements to Clang's time-trace
----------------------------------

Expand Down
35 changes: 34 additions & 1 deletion clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// The type for the C ucontext_t type.
TypeDecl *ucontext_tDecl = nullptr;

/// The type for the C fexcept_t type.
TypeDecl *fexcept_tDecl = nullptr;

/// The type for the C fenv_t type.
TypeDecl *fenv_tDecl = nullptr;

/// Type for the Block descriptor for Blocks CodeGen.
///
/// Since this is only used for generation of debug info, it is not
Expand Down Expand Up @@ -2350,6 +2356,30 @@ class ASTContext : public RefCountedBase<ASTContext> {
return QualType();
}

/// Set the type for the C fexcept_t type.
void setfexcept_tDecl(TypeDecl *fexcept_tDecl) {
this->fexcept_tDecl = fexcept_tDecl;
}

/// Retrieve the C fexcept_t type.
QualType getfexcept_tType() const {
if (fexcept_tDecl)
return getTypeDeclType(ElaboratedTypeKeyword::None,
/*Qualifier=*/std::nullopt, fexcept_tDecl);
return QualType();
}

/// Set the type for the C fenv_t type.
void setfenv_tDecl(TypeDecl *fenv_tDecl) { this->fenv_tDecl = fenv_tDecl; }

/// Retrieve the C fenv_t type.
QualType getfenv_tType() const {
if (fenv_tDecl)
return getTypeDeclType(ElaboratedTypeKeyword::None,
/*Qualifier=*/std::nullopt, fenv_tDecl);
return QualType();
}

/// The result type of logical operations, '<', '>', '!=', etc.
CanQualType getLogicalOperationType() const {
return getLangOpts().CPlusPlus ? BoolTy : IntTy;
Expand Down Expand Up @@ -2630,7 +2660,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
GE_Missing_setjmp,

/// Missing a type from <ucontext.h>
GE_Missing_ucontext
GE_Missing_ucontext,

/// Missing a type from <fenv.h>
GE_Missing_fenv
};

QualType DecodeTypeStr(const char *&Str, const ASTContext &Context,
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/BuiltinHeaders.def
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ HEADER(BLOCKS_H, "Blocks.h")
HEADER(COMPLEX_H, "complex.h")
HEADER(CTYPE_H, "ctype.h")
HEADER(EMMINTRIN_H, "emmintrin.h")
HEADER(FENV_H, "fenv.h")
HEADER(FOUNDATION_NSOBJCRUNTIME_H, "Foundation/NSObjCRuntime.h")
HEADER(IMMINTRIN_H, "immintrin.h")
HEADER(INTRIN_H, "intrin.h")
Expand Down
55 changes: 55 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4599,6 +4599,61 @@ def BlockObjectDispose : LibBuiltin<"blocks.h"> {
}
// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.

def FeClearExcept : LibBuiltin<"fenv.h"> {
let Spellings = ["feclearexcept"];
let Prototype = "int(int)";
}

def FeGetExceptFlag : LibBuiltin<"fenv.h"> {
let Spellings = ["fegetexceptflag"];
let Prototype = "int(fexcept_t*, int)";
}

def FeRaiseExcept : LibBuiltin<"fenv.h"> {
let Spellings = ["feraiseexcept"];
let Prototype = "int(int)";
}

def FeSetExceptFlag : LibBuiltin<"fenv.h"> {
let Spellings = ["fesetexceptflag"];
let Prototype = "int(fexcept_t const*, int)";
}

def FeTestExcept : LibBuiltin<"fenv.h"> {
let Spellings = ["fetestexcept"];
let Prototype = "int(int)";
}

def FeGetRound : LibBuiltin<"fenv.h"> {
let Spellings = ["fegetround"];
let Prototype = "int()";
}

def FeSetRound : LibBuiltin<"fenv.h"> {
let Spellings = ["fesetround"];
let Prototype = "int(int)";
}

def FeGetEnv : LibBuiltin<"fenv.h"> {
let Spellings = ["fegetenv"];
let Prototype = "int(fenv_t*)";
}

def FeHoldExcept : LibBuiltin<"fenv.h"> {
let Spellings = ["feholdexcept"];
let Prototype = "int(fenv_t*)";
}

def FeSetEnv : LibBuiltin<"fenv.h"> {
let Spellings = ["fesetenv"];
let Prototype = "int(fenv_t const*)";
}

def FeUpdateEnv : LibBuiltin<"fenv.h"> {
let Spellings = ["feupdateenv"];
let Prototype = "int(fenv_t const*)";
}

def __Addressof : LangBuiltin<"CXX_LANG"> {
let Spellings = ["__addressof"];
let Attributes = [FunctionWithoutBuiltinPrefix, NoThrow, Const,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,11 @@ def err_ptrauth_indirect_goto_addrlabel_arithmetic : Error<
"%select{subtraction|addition}0 of address-of-label expressions is not "
"supported with ptrauth indirect gotos">;

def warn_fe_access_without_fenv_access : Warning<
"'%0' used without enabling floating-point exception behavior; use 'pragma STDC "
"FENV_ACCESS ON' or compile with '-ffp-exception-behavior=maytrap'">,
InGroup<DiagGroup<"fenv-access">>;

// __ptrauth qualifier
def err_ptrauth_qualifier_invalid : Error<
"%select{return type|parameter type|property}1 may not be qualified with "
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,8 @@ NOTABLE_IDENTIFIER(FILE)
NOTABLE_IDENTIFIER(jmp_buf)
NOTABLE_IDENTIFIER(sigjmp_buf)
NOTABLE_IDENTIFIER(ucontext_t)
NOTABLE_IDENTIFIER(fexcept_t)
NOTABLE_IDENTIFIER(fenv_t)
NOTABLE_IDENTIFIER(float_t)
NOTABLE_IDENTIFIER(double_t)

Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -8264,6 +8264,10 @@ class Sema final : public SemaBase {
return currentEvaluationContext().isUnevaluated();
}

bool isPotentiallyEvaluatedContext() const {
return currentEvaluationContext().isPotentiallyEvaluated();
}

bool isImmediateFunctionContext() const {
return currentEvaluationContext().isImmediateFunctionContext();
}
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,13 @@ enum SpecialTypeIDs {
SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6,

/// C ucontext_t typedef type
SPECIAL_TYPE_UCONTEXT_T = 7
SPECIAL_TYPE_UCONTEXT_T = 7,

/// C fexcept_t typedef type
SPECIAL_TYPE_FEXCEPT_T = 8,

/// C fenv_t typedef type
SPECIAL_TYPE_FENV_T = 9
};

/// The number of special type IDs.
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12849,6 +12849,25 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
case 'm':
Type = Context.MFloat8Ty;
break;
case 'T':
switch (*Str++) {
case 'x': {
Type = Context.getfexcept_tType();
break;
}
case 'e': {
Type = Context.getfenv_tType();
break;
}
default: {
llvm_unreachable("Unexpected target builtin type");
}
}
if (Type.isNull()) {
Error = ASTContext::GE_Missing_fenv;
return {};
}
break;
}

// If there are modifiers and if we're allowed to parse them, go for it.
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3928,6 +3928,24 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (BuiltinCountedByRef(TheCall))
return ExprError();
break;

case Builtin::BIfeclearexcept:
case Builtin::BIfegetexceptflag:
case Builtin::BIferaiseexcept:
case Builtin::BIfesetexceptflag:
case Builtin::BIfetestexcept:
case Builtin::BIfegetround:
case Builtin::BIfesetround:
case Builtin::BIfegetenv:
case Builtin::BIfeholdexcept:
case Builtin::BIfesetenv:
case Builtin::BIfeupdateenv:
if (TheCall->getFPFeaturesInEffect(getLangOpts()).getExceptionMode() ==
LangOptions::FPE_Ignore &&
isPotentiallyEvaluatedContext()) {
Diag(TheCall->getBeginLoc(), diag::warn_fe_access_without_fenv_access)
<< FDecl->getName() << TheCall->getSourceRange();
}
}

if (getLangOpts().HLSL && HLSL().CheckBuiltinFunctionCall(BuiltinID, TheCall))
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,8 @@ static StringRef getHeaderName(Builtin::Context &BuiltinInfo, unsigned ID,
return "setjmp.h";
case ASTContext::GE_Missing_ucontext:
return "ucontext.h";
case ASTContext::GE_Missing_fenv:
return "fenv.h";
}
llvm_unreachable("unhandled error kind");
}
Expand Down Expand Up @@ -7018,6 +7020,12 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
case tok::NotableIdentifierKind::ucontext_t:
Context.setucontext_tDecl(NewTD);
break;
case tok::NotableIdentifierKind::fexcept_t:
Context.setfexcept_tDecl(NewTD);
break;
case tok::NotableIdentifierKind::fenv_t:
Context.setfenv_tDecl(NewTD);
break;
case tok::NotableIdentifierKind::float_t:
case tok::NotableIdentifierKind::double_t:
NewTD->addAttr(AvailableOnlyInDefaultEvalMethodAttr::Create(Context));
Expand Down
36 changes: 36 additions & 0 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5758,6 +5758,42 @@ void ASTReader::InitializeContext() {
}
}
}

if (TypeID Fexcept_t = SpecialTypes[SPECIAL_TYPE_FEXCEPT_T]) {
QualType Fexcept_tType = GetType(Fexcept_t);
if (Fexcept_tType.isNull()) {
Error("fexcept_t type is NULL");
return;
}

if (!Context.fexcept_tDecl) {
if (const TypedefType *Typedef = Fexcept_tType->getAs<TypedefType>())
Context.setfexcept_tDecl(Typedef->getDecl());
else {
const TagType *Tag = Fexcept_tType->getAs<TagType>();
assert(Tag && "Invalid fexcept_t type in AST file");
Context.setfexcept_tDecl(Tag->getDecl());
}
}
}

if (TypeID Fenv_t = SpecialTypes[SPECIAL_TYPE_FENV_T]) {
QualType Fenv_tType = GetType(Fenv_t);
if (Fenv_tType.isNull()) {
Error("fenv_t type is NULL");
return;
}

if (!Context.fenv_tDecl) {
if (const TypedefType *Typedef = Fenv_tType->getAs<TypedefType>())
Context.setfenv_tDecl(Typedef->getDecl());
else {
const TagType *Tag = Fenv_tType->getAs<TagType>();
assert(Tag && "Invalid fenv_t type in AST file");
Context.setfenv_tDecl(Tag->getDecl());
}
}
}
}

ReadPragmaDiagnosticMappings(Context.getDiagnostics());
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6158,6 +6158,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
AddTypeRef(Context, Context.ObjCClassRedefinitionType, SpecialTypes);
AddTypeRef(Context, Context.ObjCSelRedefinitionType, SpecialTypes);
AddTypeRef(Context, Context.getucontext_tType(), SpecialTypes);
AddTypeRef(Context, Context.getfexcept_tType(), SpecialTypes);
AddTypeRef(Context, Context.getfenv_tType(), SpecialTypes);
}

if (SemaPtr)
Expand Down
25 changes: 25 additions & 0 deletions clang/test/PCH/builtins-fenv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Test this without pch.
// RUN: %clang_cc1 -include %S/builtins-fenv.h -fsyntax-only -verify %s

// Test with pch.
// RUN: %clang_cc1 -emit-pch -o %t %S/builtins-fenv.h
// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s

// expected-no-diagnostics
fexcept_t *flagp = 0;
fenv_t *envp = 0;

void f(void) {
#pragma STDC FENV_ACCESS ON
feclearexcept(FE_INVALID);
fegetexceptflag(flagp, FE_INVALID);
feraiseexcept(FE_INVALID);
fesetexceptflag(flagp, FE_INVALID);
fetestexcept(FE_INVALID);
fegetround();
fesetround(0);
fegetenv(envp);
feholdexcept(envp);
fesetenv(envp);
feupdateenv(envp);
}
18 changes: 18 additions & 0 deletions clang/test/PCH/builtins-fenv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Header for PCH test builtins-fenv.c

#define FE_INVALID 1

typedef struct {} fenv_t;
typedef unsigned short int fexcept_t;

int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t *flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexcept(int excepts);
int fegetround(void);
int fesetround(int rounding_mode);
int fegetenv(fenv_t *envp);
int feholdexcept(fenv_t *envp);
int fesetenv(const fenv_t *envp);
int feupdateenv(const fenv_t *envp);
Loading
Loading