summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp60
1 files changed, 43 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5f12ea0b220..4c504af7a08 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1134,6 +1134,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI__sync_swap_8:
case Builtin::BI__sync_swap_16:
return SemaBuiltinAtomicOverloaded(TheCallResult);
+ case Builtin::BI__sync_synchronize:
+ Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst)
+ << TheCall->getCallee()->getSourceRange();
+ break;
case Builtin::BI__builtin_nontemporal_load:
case Builtin::BI__builtin_nontemporal_store:
return SemaBuiltinNontemporalOverloaded(TheCallResult);
@@ -4646,25 +4650,24 @@ static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) {
return false;
}
-/// SemaBuiltinAtomicOverloaded - We have a call to a function like
-/// __sync_fetch_and_add, which is an overloaded function based on the pointer
-/// type of its first argument. The main ActOnCallExpr routines have already
-/// promoted the types of arguments because all of these calls are prototyped as
-/// void(...).
+/// We have a call to a function like __sync_fetch_and_add, which is an
+/// overloaded function based on the pointer type of its first argument.
+/// The main ActOnCallExpr routines have already promoted the types of
+/// arguments because all of these calls are prototyped as void(...).
///
/// This function goes through and does final semantic checking for these
-/// builtins,
+/// builtins, as well as generating any warnings.
ExprResult
Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
- CallExpr *TheCall = (CallExpr *)TheCallResult.get();
- DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
+ CallExpr *TheCall = static_cast<CallExpr *>(TheCallResult.get());
+ Expr *Callee = TheCall->getCallee();
+ DeclRefExpr *DRE = cast<DeclRefExpr>(Callee->IgnoreParenCasts());
FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());
// Ensure that we have at least one argument to do type inference from.
if (TheCall->getNumArgs() < 1) {
Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
- << 0 << 1 << TheCall->getNumArgs()
- << TheCall->getCallee()->getSourceRange();
+ << 0 << 1 << TheCall->getNumArgs() << Callee->getSourceRange();
return ExprError();
}
@@ -4941,13 +4944,16 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
if (TheCall->getNumArgs() < 1+NumFixed) {
Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
<< 0 << 1 + NumFixed << TheCall->getNumArgs()
- << TheCall->getCallee()->getSourceRange();
+ << Callee->getSourceRange();
return ExprError();
}
+ Diag(TheCall->getEndLoc(), diag::warn_atomic_implicit_seq_cst)
+ << Callee->getSourceRange();
+
if (WarnAboutSemanticsChange) {
Diag(TheCall->getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
- << TheCall->getCallee()->getSourceRange();
+ << Callee->getSourceRange();
}
// Get the decl for the concrete builtin from this, we can tell what the
@@ -10284,6 +10290,10 @@ static void AnalyzeAssignment(Sema &S, BinaryOperator *E) {
}
AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
+
+ // Diagnose implicitly sequentially-consistent atomic assignment.
+ if (E->getLHS()->getType()->isAtomicType())
+ S.Diag(E->getRHS()->getBeginLoc(), diag::warn_atomic_implicit_seq_cst);
}
/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
@@ -10419,6 +10429,9 @@ static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
+ if (E->getLHS()->getType()->isAtomicType())
+ S.Diag(E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
+
// Now check the outermost expression
const auto *ResultBT = E->getLHS()->getType()->getAs<BuiltinType>();
const auto *RBT = cast<CompoundAssignOperator>(E)
@@ -10680,6 +10693,9 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
if (CC.isInvalid())
return;
+ if (Source->isAtomicType())
+ S.Diag(E->getExprLoc(), diag::warn_atomic_implicit_seq_cst);
+
// Diagnose implicit casts to bool.
if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {
if (isa<StringLiteral>(E))
@@ -10975,11 +10991,13 @@ static void CheckConditionalOperator(Sema &S, ConditionalOperator *E,
E->getType(), CC, &Suspicious);
}
-/// CheckBoolLikeConversion - Check conversion of given expression to boolean.
+/// Check conversion of given expression to boolean.
/// Input argument E is a logical expression.
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
if (S.getLangOpts().Bool)
return;
+ if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
+ return;
CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy, CC);
}
@@ -11024,8 +11042,10 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,
}
// Skip past explicit casts.
- if (isa<ExplicitCastExpr>(E)) {
- E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts();
+ if (auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
+ E = CE->getSubExpr()->IgnoreParenImpCasts();
+ if (!CE->getType()->isVoidType() && E->getType()->isAtomicType())
+ S.Diag(E->getBeginLoc(), diag::warn_atomic_implicit_seq_cst);
return AnalyzeImplicitConversions(S, E, CC);
}
@@ -11078,9 +11098,15 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,
::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc());
}
- if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E))
- if (U->getOpcode() == UO_LNot)
+ if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
+ if (U->getOpcode() == UO_LNot) {
::CheckBoolLikeConversion(S, U->getSubExpr(), CC);
+ } else if (U->getOpcode() != UO_AddrOf) {
+ if (U->getSubExpr()->getType()->isAtomicType())
+ S.Diag(U->getSubExpr()->getBeginLoc(),
+ diag::warn_atomic_implicit_seq_cst);
+ }
+ }
}
/// Diagnose integer type and any valid implicit conversion to it.
OpenPOWER on IntegriCloud