Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -6747,6 +6747,9 @@ class Sema final : public SemaBase {
/// example, in a for-range initializer).
bool InLifetimeExtendingContext = false;

/// Whether evaluating an expression for a switch case label.
bool IsCaseExpr = false;

/// Whether we should rebuild CXXDefaultArgExpr and CXXDefaultInitExpr.
bool RebuildDefaultArgOrDefaultInit = false;

Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ ExprResult Parser::ParseArrayBoundExpression() {
ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
EnterExpressionEvaluationContext ConstantEvaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
Actions.currentEvaluationContext().IsCaseExpr = true;

ExprResult LHS(ParseCastExpression(CastParseKind::AnyCastExpr, false,
TypeCastState::NotTypeCast));
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,11 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
return;
}
case AR_Deprecated:
// Don't diagnose deprecated values in case expressions: they still need to
// be handled for the switch to be considered covered.
if (S.currentEvaluationContext().IsCaseExpr)
return;

diag = !ObjCPropertyAccess ? diag::warn_deprecated
: diag::warn_property_method_deprecated;
diag_message = diag::warn_deprecated_message;
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Sema/SemaStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1667,8 +1667,12 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// Don't warn about omitted unavailable EnumConstantDecls.
switch (EI->second->getAvailability()) {
case AR_Deprecated:
// Omitting a deprecated constant is ok; it should never materialize.
// Deprecated enumerators need to be handled: they may be deprecated,
// but can still occur.
break;

case AR_Unavailable:
// Omitting an unavailable enumerator is ok; it should never occur.
continue;

case AR_NotYetIntroduced:
Expand Down
25 changes: 23 additions & 2 deletions clang/test/Sema/switch-availability.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -verify -Wswitch -triple x86_64-apple-macosx10.12 %s
// RUN: %clang_cc1 -verify -Wswitch -Wreturn-type -triple x86_64-apple-macosx10.12 %s

enum SwitchOne {
Unavail __attribute__((availability(macos, unavailable))),
Expand All @@ -15,7 +15,7 @@ enum SwitchTwo {
};

void testSwitchTwo(enum SwitchTwo st) {
switch (st) {} // expected-warning{{enumeration values 'Vim' and 'Emacs' not handled in switch}}
switch (st) {} // expected-warning{{enumeration values 'Ed', 'Vim', and 'Emacs' not handled in switch}}
}

enum SwitchThree {
Expand All @@ -25,3 +25,24 @@ enum SwitchThree {
void testSwitchThree(enum SwitchThree st) {
switch (st) {} // expected-warning{{enumeration value 'New' not handled in switch}}
}

enum SwitchFour {
Red,
Green,
Blue [[deprecated]]
};

int testSwitchFour(enum SwitchFour e) {
switch (e) { // expected-warning{{enumeration value 'Blue' not handled in switch}}
case Red: return 1;
case Green: return 2;
}
} // expected-warning{{non-void function does not return a value in all control paths}}

int testSwitchFourCovered(enum SwitchFour e) {
switch (e) {
case Red: return 1;
case Green: return 2;
case Blue: return 3; // no warning
}
}
6 changes: 3 additions & 3 deletions clang/test/SemaObjC/unguarded-availability.m
Original file line number Diff line number Diff line change
Expand Up @@ -343,21 +343,21 @@ @interface BaseClass (CategoryWithNewProtocolRequirement) <NewProtocol>
@end

typedef enum {
AK_Dodo __attribute__((availability(macos, deprecated=10.3))), // expected-note 3 {{marked deprecated here}}
AK_Dodo __attribute__((availability(macos, deprecated=10.3))), // expected-note 1 {{marked deprecated here}}
AK_Cat __attribute__((availability(macos, introduced=10.4))),
AK_CyborgCat __attribute__((availability(macos, introduced=10.12))), // expected-note {{'AK_CyborgCat' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9}}
} Animals;

void switchAnimals(Animals a) {
switch (a) {
case AK_Dodo: break; // expected-warning{{'AK_Dodo' is deprecated}}
case AK_Dodo: break; // no warn
case AK_Cat: break;
case AK_Cat|AK_CyborgCat: break; // expected-warning{{case value not in enum}}
case AK_CyborgCat: break; // no warn
}

switch (a) {
case AK_Dodo...AK_CyborgCat: // expected-warning {{'AK_Dodo' is depr}}
case AK_Dodo...AK_CyborgCat: // no warn
break;
}

Expand Down
Loading