-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[HLSL] Strict Availability Diagnostics #93860
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
Changes from all commits
532f10f
1aa3b1c
33c54e4
78a02c7
cb1f4e9
a689a24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,6 +157,20 @@ static bool ShouldDiagnoseAvailabilityInContext( | |
} | ||
} | ||
|
||
// In HLSL, skip emitting diagnostic if the diagnostic mode is not set to | ||
// strict (-fhlsl-strict-availability), or if the target is library and the | ||
// availability is restricted to a specific environment/shader stage. | ||
// For libraries the availability will be checked later in | ||
// DiagnoseHLSLAvailability class once where the specific environment/shader | ||
// stage of the caller is known. | ||
if (S.getLangOpts().HLSL) { | ||
if (!S.getLangOpts().HLSLStrictAvailability || | ||
(DeclEnv != nullptr && | ||
S.getASTContext().getTargetInfo().getTriple().getEnvironment() == | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here (and a bit further down in the PR as well) there are places that assume that "not library" implies "known target stage". I wonder if we're opening ourselves up to subtle bugs issues in the future if we end up adding another library-like target? Maybe this is unlikely enough that we can deal with that later? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that is the current assumption everywhere - it is either library or a shader with a known target stage. Unless you see any potential library-like target on the horizon I think we can leave it like that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @llvm-beanz mentioned something this morning (non-DXIL outputs ready to drive LTO) that made me think there may be a possibility of another environment that isn't a library shader, but also isn't tied to a specific shader stage. I may have misunderstood though. If we've already got a load of code making this same assumption then maybe now isn't the right time to tackle it anyway. Happy for no change here. |
||
llvm::Triple::EnvironmentType::Library)) | ||
return false; | ||
} | ||
damyanp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Checks if we should emit the availability diagnostic in the context of C. | ||
auto CheckContext = [&](const Decl *C) { | ||
if (K == AR_NotYetIntroduced) { | ||
|
@@ -210,13 +224,16 @@ static bool ShouldDiagnoseAvailabilityInContext( | |
return true; | ||
} | ||
|
||
static bool | ||
shouldDiagnoseAvailabilityByDefault(const ASTContext &Context, | ||
const VersionTuple &DeploymentVersion, | ||
const VersionTuple &DeclVersion) { | ||
static unsigned getAvailabilityDiagnosticKind( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if it is the best, but that's what |
||
const ASTContext &Context, const VersionTuple &DeploymentVersion, | ||
const VersionTuple &DeclVersion, bool HasMatchingEnv) { | ||
const auto &Triple = Context.getTargetInfo().getTriple(); | ||
VersionTuple ForceAvailabilityFromVersion; | ||
switch (Triple.getOS()) { | ||
// For iOS, emit the diagnostic even if -Wunguarded-availability is | ||
// not specified for deployment targets >= to iOS 11 or equivalent or | ||
// for declarations that were introduced in iOS 11 (macOS 10.13, ...) or | ||
// later. | ||
case llvm::Triple::IOS: | ||
case llvm::Triple::TvOS: | ||
ForceAvailabilityFromVersion = VersionTuple(/*Major=*/11); | ||
|
@@ -228,16 +245,26 @@ shouldDiagnoseAvailabilityByDefault(const ASTContext &Context, | |
case llvm::Triple::MacOSX: | ||
ForceAvailabilityFromVersion = VersionTuple(/*Major=*/10, /*Minor=*/13); | ||
break; | ||
// For HLSL, use diagnostic from HLSLAvailability group which | ||
// are reported as errors by default and in strict diagnostic mode | ||
// (-fhlsl-strict-availability) and as warnings in relaxed diagnostic | ||
// mode (-Wno-error=hlsl-availability) | ||
case llvm::Triple::ShaderModel: | ||
// FIXME: This will be updated when HLSL strict diagnostic mode | ||
// is implemented (issue #90096) | ||
return false; | ||
return HasMatchingEnv ? diag::warn_hlsl_availability | ||
: diag::warn_hlsl_availability_unavailable; | ||
default: | ||
// New targets should always warn about availability. | ||
return Triple.getVendor() == llvm::Triple::Apple; | ||
// New Apple targets should always warn about availability. | ||
ForceAvailabilityFromVersion = | ||
(Triple.getVendor() == llvm::Triple::Apple) | ||
? VersionTuple(/*Major=*/0, 0) | ||
: VersionTuple(/*Major=*/(unsigned)-1, (unsigned)-1); | ||
} | ||
return DeploymentVersion >= ForceAvailabilityFromVersion || | ||
DeclVersion >= ForceAvailabilityFromVersion; | ||
if (DeploymentVersion >= ForceAvailabilityFromVersion || | ||
DeclVersion >= ForceAvailabilityFromVersion) | ||
return HasMatchingEnv ? diag::warn_unguarded_availability_new | ||
: diag::warn_unguarded_availability_unavailable_new; | ||
return HasMatchingEnv ? diag::warn_unguarded_availability | ||
: diag::warn_unguarded_availability_unavailable; | ||
} | ||
|
||
static NamedDecl *findEnclosingDeclToAnnotate(Decl *OrigCtx) { | ||
|
@@ -410,26 +437,16 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, | |
const TargetInfo &TI = S.getASTContext().getTargetInfo(); | ||
std::string PlatformName( | ||
AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName())); | ||
llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName( | ||
TI.getTriple().getEnvironment())); | ||
llvm::StringRef TargetEnvironment( | ||
llvm::Triple::getEnvironmentTypeName(TI.getTriple().getEnvironment())); | ||
llvm::StringRef AttrEnvironment = | ||
AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName( | ||
AvailabilityAttr::getEnvironmentType( | ||
AA->getEnvironment()->getName())) | ||
: ""; | ||
AA->getEnvironment() ? AA->getEnvironment()->getName() : ""; | ||
bool UseEnvironment = | ||
(!AttrEnvironment.empty() && !TargetEnvironment.empty()); | ||
|
||
bool UseNewWarning = shouldDiagnoseAvailabilityByDefault( | ||
unsigned DiagKind = getAvailabilityDiagnosticKind( | ||
S.Context, S.Context.getTargetInfo().getPlatformMinVersion(), | ||
Introduced); | ||
|
||
unsigned DiagKind = | ||
EnvironmentMatchesOrNone | ||
? (UseNewWarning ? diag::warn_unguarded_availability_new | ||
: diag::warn_unguarded_availability) | ||
: (UseNewWarning ? diag::warn_unguarded_availability_unavailable_new | ||
: diag::warn_unguarded_availability_unavailable); | ||
Introduced, EnvironmentMatchesOrNone); | ||
|
||
S.Diag(Loc, DiagKind) << OffendingDecl << PlatformName | ||
<< Introduced.getAsString() << UseEnvironment | ||
|
@@ -834,34 +851,19 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( | |
OffendingDecl)) | ||
return; | ||
|
||
// We would like to emit the diagnostic even if -Wunguarded-availability is | ||
// not specified for deployment targets >= to iOS 11 or equivalent or | ||
// for declarations that were introduced in iOS 11 (macOS 10.13, ...) or | ||
// later. | ||
bool UseNewDiagKind = shouldDiagnoseAvailabilityByDefault( | ||
SemaRef.Context, | ||
SemaRef.Context.getTargetInfo().getPlatformMinVersion(), Introduced); | ||
|
||
const TargetInfo &TI = SemaRef.getASTContext().getTargetInfo(); | ||
std::string PlatformName( | ||
AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName())); | ||
llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName( | ||
TI.getTriple().getEnvironment())); | ||
llvm::StringRef TargetEnvironment(TI.getTriple().getEnvironmentName()); | ||
llvm::StringRef AttrEnvironment = | ||
AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName( | ||
AvailabilityAttr::getEnvironmentType( | ||
AA->getEnvironment()->getName())) | ||
: ""; | ||
AA->getEnvironment() ? AA->getEnvironment()->getName() : ""; | ||
bool UseEnvironment = | ||
(!AttrEnvironment.empty() && !TargetEnvironment.empty()); | ||
|
||
unsigned DiagKind = | ||
EnvironmentMatchesOrNone | ||
? (UseNewDiagKind ? diag::warn_unguarded_availability_new | ||
: diag::warn_unguarded_availability) | ||
: (UseNewDiagKind | ||
? diag::warn_unguarded_availability_unavailable_new | ||
: diag::warn_unguarded_availability_unavailable); | ||
unsigned DiagKind = getAvailabilityDiagnosticKind( | ||
SemaRef.Context, | ||
SemaRef.Context.getTargetInfo().getPlatformMinVersion(), Introduced, | ||
EnvironmentMatchesOrNone); | ||
|
||
SemaRef.Diag(Range.getBegin(), DiagKind) | ||
<< Range << D << PlatformName << Introduced.getAsString() | ||
|
Uh oh!
There was an error while loading. Please reload this page.