diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 60 |
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. |

