Revert "Diagnose -Wunused-value based on CFG reachability"
This reverts commit cbbf2e8c8a
.
It seems causing diagnoses in SFINAE context.
This commit is contained in:
parent
cc3c788ad2
commit
59337263ab
|
@ -8565,9 +8565,6 @@ def err_typecheck_choose_expr_requires_constant : Error<
|
|||
"'__builtin_choose_expr' requires a constant expression">;
|
||||
def warn_unused_expr : Warning<"expression result unused">,
|
||||
InGroup<UnusedValue>;
|
||||
def warn_unused_comma_left_operand : Warning<
|
||||
"left operand of comma operator has no effect">,
|
||||
InGroup<UnusedValue>;
|
||||
def warn_unused_voidptr : Warning<
|
||||
"expression result unused; should this cast be to 'void'?">,
|
||||
InGroup<UnusedValue>;
|
||||
|
|
|
@ -4912,7 +4912,7 @@ public:
|
|||
|
||||
/// DiagnoseUnusedExprResult - If the statement passed in is an expression
|
||||
/// whose result is unused, warn.
|
||||
void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID);
|
||||
void DiagnoseUnusedExprResult(const Stmt *S);
|
||||
void DiagnoseUnusedNestedTypedefs(const RecordDecl *D);
|
||||
void DiagnoseUnusedDecl(const NamedDecl *ND);
|
||||
|
||||
|
@ -5118,16 +5118,6 @@ public:
|
|||
/// conversion.
|
||||
ExprResult tryConvertExprToType(Expr *E, QualType Ty);
|
||||
|
||||
/// Conditionally issue a diagnostic based on the statement's reachability
|
||||
/// analysis evaluation context.
|
||||
///
|
||||
/// \param Statement If Statement is non-null, delay reporting the
|
||||
/// diagnostic until the function body is parsed, and then do a basic
|
||||
/// reachability analysis to determine if the statement is reachable.
|
||||
/// If it is unreachable, the diagnostic will not be emitted.
|
||||
bool DiagIfReachable(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
|
||||
const PartialDiagnostic &PD);
|
||||
|
||||
/// Conditionally issue a diagnostic based on the current
|
||||
/// evaluation context.
|
||||
///
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/DiagnosticSema.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
|
@ -13372,7 +13371,7 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
|
|||
if (LHS.isInvalid())
|
||||
return QualType();
|
||||
|
||||
S.DiagnoseUnusedExprResult(LHS.get(), diag::warn_unused_comma_left_operand);
|
||||
S.DiagnoseUnusedExprResult(LHS.get());
|
||||
|
||||
if (!S.getLangOpts().CPlusPlus) {
|
||||
RHS = S.DefaultFunctionArrayLvalueConversion(RHS.get());
|
||||
|
@ -18899,38 +18898,6 @@ void Sema::MarkDeclarationsReferencedInExpr(Expr *E,
|
|||
EvaluatedExprMarker(*this, SkipLocalVariables).Visit(E);
|
||||
}
|
||||
|
||||
/// Emit a diagnostic when statements are reachable.
|
||||
/// FIXME: check for reachability even in expressions for which we don't build a
|
||||
/// CFG (eg, in the initializer of a global or in a constant expression).
|
||||
/// For example,
|
||||
/// namespace { auto *p = new double[3][false ? (1, 2) : 3]; }
|
||||
bool Sema::DiagIfReachable(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
|
||||
const PartialDiagnostic &PD) {
|
||||
if (!Stmts.empty() && getCurFunctionOrMethodDecl()) {
|
||||
if (!FunctionScopes.empty())
|
||||
FunctionScopes.back()->PossiblyUnreachableDiags.push_back(
|
||||
sema::PossiblyUnreachableDiag(PD, Loc, Stmts));
|
||||
return true;
|
||||
}
|
||||
|
||||
// The initializer of a constexpr variable or of the first declaration of a
|
||||
// static data member is not syntactically a constant evaluated constant,
|
||||
// but nonetheless is always required to be a constant expression, so we
|
||||
// can skip diagnosing.
|
||||
// FIXME: Using the mangling context here is a hack.
|
||||
if (auto *VD = dyn_cast_or_null<VarDecl>(
|
||||
ExprEvalContexts.back().ManglingContextDecl)) {
|
||||
if (VD->isConstexpr() ||
|
||||
(VD->isStaticDataMember() && VD->isFirstDecl() && !VD->isInline()))
|
||||
return false;
|
||||
// FIXME: For any other kind of variable, we should build a CFG for its
|
||||
// initializer and check whether the context in question is reachable.
|
||||
}
|
||||
|
||||
Diag(Loc, PD);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Emit a diagnostic that describes an effect on the run-time behavior
|
||||
/// of the program being compiled.
|
||||
///
|
||||
|
@ -18963,7 +18930,28 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts,
|
|||
|
||||
case ExpressionEvaluationContext::PotentiallyEvaluated:
|
||||
case ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
|
||||
return DiagIfReachable(Loc, Stmts, PD);
|
||||
if (!Stmts.empty() && getCurFunctionOrMethodDecl()) {
|
||||
FunctionScopes.back()->PossiblyUnreachableDiags.
|
||||
push_back(sema::PossiblyUnreachableDiag(PD, Loc, Stmts));
|
||||
return true;
|
||||
}
|
||||
|
||||
// The initializer of a constexpr variable or of the first declaration of a
|
||||
// static data member is not syntactically a constant evaluated constant,
|
||||
// but nonetheless is always required to be a constant expression, so we
|
||||
// can skip diagnosing.
|
||||
// FIXME: Using the mangling context here is a hack.
|
||||
if (auto *VD = dyn_cast_or_null<VarDecl>(
|
||||
ExprEvalContexts.back().ManglingContextDecl)) {
|
||||
if (VD->isConstexpr() ||
|
||||
(VD->isStaticDataMember() && VD->isFirstDecl() && !VD->isInline()))
|
||||
break;
|
||||
// FIXME: For any other kind of variable, we should build a CFG for its
|
||||
// initializer and check whether the context in question is reachable.
|
||||
}
|
||||
|
||||
Diag(Loc, PD);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -8523,7 +8523,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
|
|||
if (FullExpr.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
DiagnoseUnusedExprResult(FullExpr.get(), diag::warn_unused_expr);
|
||||
DiagnoseUnusedExprResult(FullExpr.get());
|
||||
}
|
||||
|
||||
FullExpr = CorrectDelayedTyposInExpr(FullExpr.get(), /*InitDecl=*/nullptr,
|
||||
|
|
|
@ -216,9 +216,9 @@ static bool DiagnoseNoDiscard(Sema &S, const WarnUnusedResultAttr *A,
|
|||
return S.Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2;
|
||||
}
|
||||
|
||||
void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {
|
||||
void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
|
||||
if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
|
||||
return DiagnoseUnusedExprResult(Label->getSubStmt(), DiagID);
|
||||
return DiagnoseUnusedExprResult(Label->getSubStmt());
|
||||
|
||||
const Expr *E = dyn_cast_or_null<Expr>(S);
|
||||
if (!E)
|
||||
|
@ -264,6 +264,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {
|
|||
// Okay, we have an unused result. Depending on what the base expression is,
|
||||
// we might want to make a more specific diagnostic. Check for one of these
|
||||
// cases now.
|
||||
unsigned DiagID = diag::warn_unused_expr;
|
||||
if (const FullExpr *Temps = dyn_cast<FullExpr>(E))
|
||||
E = Temps->getSubExpr();
|
||||
if (const CXXBindTemporaryExpr *TempExpr = dyn_cast<CXXBindTemporaryExpr>(E))
|
||||
|
@ -338,7 +339,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {
|
|||
if (LangOpts.OpenMP && isa<CallExpr>(Source) &&
|
||||
POE->getNumSemanticExprs() == 1 &&
|
||||
isa<CallExpr>(POE->getSemanticExpr(0)))
|
||||
return DiagnoseUnusedExprResult(POE->getSemanticExpr(0), DiagID);
|
||||
return DiagnoseUnusedExprResult(POE->getSemanticExpr(0));
|
||||
if (isa<ObjCSubscriptRefExpr>(Source))
|
||||
DiagID = diag::warn_unused_container_subscript_expr;
|
||||
else
|
||||
|
@ -378,8 +379,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {
|
|||
return;
|
||||
}
|
||||
|
||||
DiagIfReachable(Loc, S ? llvm::makeArrayRef(S) : llvm::None,
|
||||
PDiag(DiagID) << R1 << R2);
|
||||
DiagRuntimeBehavior(Loc, nullptr, PDiag(DiagID) << R1 << R2);
|
||||
}
|
||||
|
||||
void Sema::ActOnStartOfCompoundStmt(bool IsStmtExpr) {
|
||||
|
|
|
@ -339,12 +339,12 @@ void f22() {
|
|||
(void)(0 && x);
|
||||
(void)y7;
|
||||
(void)(0 || (y8, ({ return; }), 1));
|
||||
// non-nested-warning@-1 {{left operand of comma operator has no effect}}
|
||||
// non-nested-warning@-1 {{expression result unused}}
|
||||
(void)x;
|
||||
break;
|
||||
case 8:
|
||||
(void)(1 && (y9, ({ return; }), 1));
|
||||
// non-nested-warning@-1 {{left operand of comma operator has no effect}}
|
||||
// non-nested-warning@-1 {{expression result unused}}
|
||||
(void)x;
|
||||
break;
|
||||
case 9:
|
||||
|
|
|
@ -27,7 +27,7 @@ extern Linkage1 linkage1f();
|
|||
void linkage2f(Linkage2);
|
||||
|
||||
void use_linkage() {
|
||||
&linkage1v, &linkage1iv, &linkage2v, &linkage2iv, &linkaget1v; // expected-warning 4{{left operand of comma operator has no effect}} expected-warning {{unused}}
|
||||
&linkage1v, &linkage1iv, &linkage2v, &linkage2iv, &linkaget1v; // expected-warning 5{{unused}}
|
||||
linkage1f();
|
||||
linkage2f({});
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace dr1413 { // dr1413: 12
|
|||
Check<true ? 0 : A::unknown_spec>::type *var1; // expected-error {{undeclared identifier 'var1'}}
|
||||
Check<true ? 0 : a>::type *var2; // ok, variable declaration expected-note 0+{{here}}
|
||||
Check<true ? 0 : b>::type *var3; // expected-error {{undeclared identifier 'var3'}}
|
||||
Check<true ? 0 : ((void)c, 0)>::type *var4; // expected-error {{undeclared identifier 'var4'}}
|
||||
Check<true ? 0 : (c, 0)>::type *var4; // expected-error {{undeclared identifier 'var4'}}
|
||||
// value-dependent because of the implied type-dependent 'this->', not because of 'd'
|
||||
Check<true ? 0 : (d(), 0)>::type *var5; // expected-error {{undeclared identifier 'var5'}}
|
||||
// value-dependent because of the value-dependent '&' operator, not because of 'A::d'
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace dr2083 { // dr2083: partial
|
|||
a.*&A::x; // expected-warning {{unused}}
|
||||
true ? a.x : a.y; // expected-warning {{unused}}
|
||||
(void)a.x;
|
||||
a.x, discarded_lval(); // expected-warning {{left operand of comma operator has no effect}}
|
||||
a.x, discarded_lval(); // expected-warning {{unused}}
|
||||
#if 1 // FIXME: These errors are all incorrect; the above code is valid.
|
||||
// expected-error@-6 {{enclosing function}}
|
||||
// expected-error@-6 {{enclosing function}}
|
||||
|
|
|
@ -26,12 +26,12 @@ namespace dr712 { // dr712: partial
|
|||
use(a);
|
||||
use((a));
|
||||
use(cond ? a : a);
|
||||
use((cond, a)); // expected-warning 2{{left operand of comma operator has no effect}} FIXME: should only warn once
|
||||
use((cond, a)); // expected-warning 2{{unused}} FIXME: should only warn once
|
||||
|
||||
(void)a; // FIXME: expected-error {{declared in enclosing}}
|
||||
(void)(a); // FIXME: expected-error {{declared in enclosing}}
|
||||
(void)(cond ? a : a); // FIXME: expected-error 2{{declared in enclosing}}
|
||||
(void)(cond, a); // FIXME: expected-error {{declared in enclosing}} expected-warning {{left operand of comma operator has no effect}}
|
||||
(void)(cond, a); // FIXME: expected-error {{declared in enclosing}} expected-warning {{unused}}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace class_templates
|
|||
template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
|
||||
struct B<T**> {};
|
||||
|
||||
static_assert(((void)B<int**>{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B<int *>' required here}}
|
||||
static_assert((B<int**>{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B<int *>' required here}}
|
||||
// expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B<int>' required here}}
|
||||
// expected-note@-2{{during template argument deduction for class template partial specialization 'B<T *>' [with T = int *]}}
|
||||
// expected-note@-3{{during template argument deduction for class template partial specialization 'B<T **>' [with T = int]}}
|
||||
|
|
|
@ -12,7 +12,7 @@ void completeParam(int param) {
|
|||
|
||||
void completeParamPragmaError(int param) {
|
||||
Outer(__extension__({ _Pragma(2) })); // expected-error {{_Pragma takes a parenthesized string literal}}
|
||||
param;
|
||||
param; // expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | FileCheck %s
|
||||
|
|
|
@ -14,7 +14,7 @@ int fn1() {
|
|||
int fn2() {
|
||||
union a m;
|
||||
m.x = 7, 5.6k; // expected-warning {{expression result unused}}
|
||||
return m.x, m.i; // expected-warning {{left operand of comma operator has no effect}}
|
||||
return m.x, m.i; // expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
_Accum acc = (0.5r, 6.9k); // expected-warning {{left operand of comma operator has no effect}}
|
||||
_Accum acc = (0.5r, 6.9k); // expected-warning {{expression result unused}}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace inheriting_constructor {
|
|||
|
||||
template<typename X, typename Y> struct T {
|
||||
template<typename A>
|
||||
explicit(((void)Y{}, true)) T(A &&a) {}
|
||||
explicit((Y{}, true)) T(A &&a) {}
|
||||
};
|
||||
|
||||
template<typename X, typename Y> struct U : T<X, Y> {
|
||||
|
@ -28,7 +28,7 @@ namespace inheriting_constructor {
|
|||
U<S, char> a = foo('0');
|
||||
}
|
||||
|
||||
//CHECK: explicit(((void)char{} , true))
|
||||
//CHECK: explicit((char{} , true))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ void arr() {
|
|||
|
||||
// This is array indexing not an array declarator because a comma expression
|
||||
// is not syntactically a constant-expression.
|
||||
int(x[1,1]); // expected-warning {{left operand of comma operator has no effect}} expected-warning {{unused}}
|
||||
int(x[1,1]); // expected-warning 2{{unused}}
|
||||
|
||||
// This is array indexing not an array declaration because a braced-init-list
|
||||
// is not syntactically a constant-expression.
|
||||
|
@ -36,8 +36,8 @@ void arr() {
|
|||
int(a[{0}]); // expected-warning {{unused}}
|
||||
|
||||
// These are array declarations.
|
||||
int(x[((void)1,1)]); // expected-error {{redefinition}}
|
||||
int(x[true ? 1 : (1,1)]); // expected-error {{redefinition}} // expected-warning {{left operand of comma operator has no effect}}
|
||||
int(x[(1,1)]); // expected-error {{redefinition}}
|
||||
int(x[true ? 1,1 : 1]); // expected-error {{redefinition}}
|
||||
|
||||
int (*_Atomic atomic_ptr_to_int);
|
||||
*atomic_ptr_to_int = 42;
|
||||
|
|
|
@ -163,7 +163,7 @@ namespace ellipsis {
|
|||
(void)p1;
|
||||
|
||||
UnsignedTmplArgSink<T(CtorSink(t ...)) ...> *t0; // ok
|
||||
UnsignedTmplArgSink<((T *)0, 42u) ...> **t0p = &t0; // expected-warning 2{{left operand of comma operator has no effect}}
|
||||
UnsignedTmplArgSink<((T *)0, 42u) ...> **t0p = &t0;
|
||||
}
|
||||
|
||||
template void foo(int, int, int); // expected-note {{in instantiation of function template specialization 'ellipsis::foo<int, int>' requested here}}
|
||||
|
|
|
@ -14,8 +14,8 @@ int f() {
|
|||
|
||||
// init-statement expressions
|
||||
if (T{f()}; f()) {} // expected-warning {{expression result unused}}
|
||||
if (T{f()}, g, h; f()) {} // expected-warning 2{{left operand of comma operator has no effect}} expected-warning {{expression result unused}}
|
||||
if (T(f()), g, h + 1; f()) {} // expected-warning 2{{left operand of comma operator has no effect}} expected-warning {{expression result unused}}
|
||||
if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}}
|
||||
if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}}
|
||||
|
||||
// condition declarations
|
||||
if (T(n){g}) {}
|
||||
|
@ -26,8 +26,8 @@ int f() {
|
|||
// condition expressions
|
||||
if (T(f())) {}
|
||||
if (T{f()}) {}
|
||||
if (T(f()), g, h) {} // expected-warning 2{{left operand of comma operator has no effect}}
|
||||
if (T{f()}, g, h) {} // expected-warning 2{{left operand of comma operator has no effect}}
|
||||
if (T(f()), g, h) {} // expected-warning 2{{unused}}
|
||||
if (T{f()}, g, h) {} // expected-warning 2{{unused}}
|
||||
|
||||
// none of the above, disambiguated as expression (can't be a declaration)
|
||||
if (T(n)(g)) {} // expected-error {{undeclared identifier 'n'}}
|
||||
|
|
|
@ -7,20 +7,20 @@ int main ()
|
|||
[a ii]; // expected-warning{{not found}}
|
||||
[a if: 1 :2]; // expected-warning{{not found}}
|
||||
[a inout: 1 :2 another:(2,3,4)]; // expected-warning{{not found}} \
|
||||
// expected-warning 2{{left operand of comma operator has no effect}}
|
||||
// expected-warning 2{{expression result unused}}
|
||||
[a inout: 1 :2 another:(2,3,4), 6,6,8]; // expected-warning{{not found}} \
|
||||
// expected-warning 2{{left operand of comma operator has no effect}}
|
||||
// expected-warning 2{{expression result unused}}
|
||||
[a inout: 1 :2 another:(2,3,4), (6,4,5),6,8]; // expected-warning{{not found}} \
|
||||
// expected-warning 4{{left operand of comma operator has no effect}}
|
||||
// expected-warning 4{{expression result unused}}
|
||||
[a inout: 1 :2 another:(i+10), (i,j-1,5),6,8]; // expected-warning{{not found}} \
|
||||
// expected-warning 2{{left operand of comma operator has no effect}}
|
||||
// expected-warning 2{{expression result unused}}
|
||||
[a long: 1 :2 another:(i+10), (i,j-1,5),6,8]; // expected-warning{{not found}} \
|
||||
// expected-warning 2{{left operand of comma operator has no effect}}
|
||||
// expected-warning 2{{expression result unused}}
|
||||
[a : "Hello\n" :2 another:(i+10), (i,j-1,5),6,8]; // expected-warning{{not found}} \
|
||||
// expected-warning 2{{left operand of comma operator has no effect}}
|
||||
// expected-warning 2{{expression result unused}}
|
||||
|
||||
// Comma expression as receiver (rdar://6222856)
|
||||
[a, b, c foo]; // expected-warning{{not found}} \
|
||||
// expected-warning 2{{left operand of comma operator has no effect}}
|
||||
// expected-warning 2{{expression result unused}}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,13 +28,14 @@ void * foo()
|
|||
}
|
||||
@catch (Frob* ex) {
|
||||
@throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}} \
|
||||
// expected-warning {{left operand of comma operator has no effect}}
|
||||
// expected-warning {{expression result unused}}
|
||||
}
|
||||
@catch (float x) { // expected-error {{@catch parameter is not a pointer to an interface type}}
|
||||
|
||||
}
|
||||
@catch(...) {
|
||||
@throw (4,3,proc()); // expected-warning 2{{left operand of comma operator has no effect}}
|
||||
@throw (4,3,proc()); // expected-warning {{expression result unused}} \
|
||||
// expected-warning {{expression result unused}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ void f(X *noreturn) {
|
|||
|
||||
// A message send which contains a message send is OK.
|
||||
[ [ X alloc ] init ];
|
||||
[ [ int(), noreturn getSelf ] getSize ]; // expected-warning {{left operand of comma operator has no effect}}
|
||||
[ [ int(), noreturn getSelf ] getSize ]; // expected-warning {{unused}}
|
||||
|
||||
// A message send which contains a lambda is OK.
|
||||
[ [noreturn] { return noreturn; } () setSize: 4 ];
|
||||
|
|
|
@ -74,7 +74,7 @@ const _Bool constbool = 0;
|
|||
EVAL_EXPR(35, constbool)
|
||||
EVAL_EXPR(36, constbool)
|
||||
|
||||
EVAL_EXPR(37, ((void)1,2.0) == 2.0 ? 1 : -1)
|
||||
EVAL_EXPR(37, (1,2.0) == 2.0 ? 1 : -1)
|
||||
EVAL_EXPR(38, __builtin_expect(1,1) == 1 ? 1 : -1)
|
||||
|
||||
// PR7884
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// This test should be left as is, as it also tests CFG functionality.
|
||||
void radar9171946() {
|
||||
if (0) {
|
||||
0 / (0 ? 1 : 0); // no-warning
|
||||
0 / (0 ? 1 : 0); // expected-warning {{expression result unused}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,12 +70,10 @@ char y[__builtin_constant_p(expr) ? -1 : 1];
|
|||
char z[__builtin_constant_p(4) ? 1 : -1];
|
||||
|
||||
// Comma tests
|
||||
int comma1[0?1,2:3]; // expected-warning {{left operand of comma operator has no effect}}
|
||||
int comma2[1 || (1, 2)]; // expected-warning {{use of logical '||' with constant operand}} \
|
||||
// expected-note {{use '|' for a bitwise operation}} \
|
||||
// expected-warning {{left operand of comma operator has no effect}}
|
||||
int comma3[(1, 2)]; // expected-warning {{variable length array folded to constant array as an extension}} \
|
||||
// expected-warning {{left operand of comma operator has no effect}}
|
||||
int comma1[0?1,2:3];
|
||||
int comma2[1||(1,2)]; // expected-warning {{use of logical '||' with constant operand}} \
|
||||
// expected-note {{use '|' for a bitwise operation}}
|
||||
int comma3[(1,2)]; // expected-warning {{variable length array folded to constant array as an extension}}
|
||||
|
||||
// Pointer + __builtin_constant_p
|
||||
char pbcp[__builtin_constant_p(4) ? (intptr_t)&expr : 0]; // expected-error {{variable length array declaration not allowed at file scope}}
|
||||
|
|
|
@ -76,9 +76,9 @@ void func(int sel) {
|
|||
|
||||
(void)local_int8;
|
||||
|
||||
local_int8, 0; // expected-warning {{left operand of comma operator has no effect}}
|
||||
local_int8, 0; // expected-warning + {{expression result unused}}
|
||||
|
||||
0, local_int8; // expected-warning {{left operand of comma operator has no effect}} expected-warning {{expression result unused}}
|
||||
0, local_int8; // expected-warning + {{expression result unused}}
|
||||
|
||||
svint8_t init_int8 = local_int8;
|
||||
svint8_t bad_init_int8 = for; // expected-error {{expected expression}}
|
||||
|
|
|
@ -50,7 +50,7 @@ int f(int i) {
|
|||
return 0;
|
||||
}
|
||||
return (i, 65537) * 65537; // expected-warning {{overflow in expression; result is 131073 with type 'int'}} \
|
||||
// expected-warning {{left operand of comma operator has no effect}}
|
||||
// expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
// rdar://18405357
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
// a different codepath when we have already emitted an error.)
|
||||
|
||||
int PotentiallyEvaluatedSizeofWarn(int n) {
|
||||
return (int)sizeof *(0 << 32,(int(*)[n])0); // expected-warning {{left operand of comma operator has no effect}} expected-warning {{shift count >= width of type}}
|
||||
return (int)sizeof *(0 << 32,(int(*)[n])0); // expected-warning {{expression result unused}} expected-warning {{shift count >= width of type}}
|
||||
}
|
||||
|
||||
void PotentiallyEvaluatedTypeofWarn(int n) {
|
||||
__typeof(*(0 << 32,(int(*)[n])0)) x; // expected-warning {{left operand of comma operator has no effect}} expected-warning {{shift count >= width of type}}
|
||||
__typeof(*(0 << 32,(int(*)[n])0)) x; // expected-warning {{expression result unused}} expected-warning {{shift count >= width of type}}
|
||||
(void)x;
|
||||
}
|
||||
|
||||
void PotentiallyEvaluatedArrayBoundWarn(int n) {
|
||||
(void)*(int(*)[(0 << 32,n)])0; // expected-warning {{left operand of comma operator has no effect}}
|
||||
(void)*(int(*)[(0 << 32,n)])0; // FIXME: We should warn here.
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ void test_argument_with_type_tag(struct flock *f)
|
|||
void test_tag_expresssion(int b) {
|
||||
fcntl(0, b ? F_DUPFD : F_SETLK, 10); // no-warning
|
||||
fcntl(0, b + F_DUPFD, 10); // no-warning
|
||||
fcntl(0, (b, F_DUPFD), 10); // expected-warning {{left operand of comma operator has no effect}}
|
||||
fcntl(0, (b, F_DUPFD), 10); // expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
// Check that using 64-bit magic values as tags works and tag values do not
|
||||
|
|
|
@ -9,31 +9,31 @@ void foo();
|
|||
|
||||
// PR4806
|
||||
void pr4806() {
|
||||
1,foo(); // expected-warning {{left operand of comma operator has no effect}}
|
||||
1,foo(); // expected-warning {{expression result unused}}
|
||||
|
||||
// other
|
||||
foo();
|
||||
i; // expected-warning {{expression result unused}}
|
||||
|
||||
i,foo(); // expected-warning {{left operand of comma operator has no effect}}
|
||||
i,foo(); // expected-warning {{expression result unused}}
|
||||
foo(),i; // expected-warning {{expression result unused}}
|
||||
|
||||
i,j,foo(); // expected-warning 2{{left operand of comma operator has no effect}}
|
||||
i,foo(),j; // expected-warning {{left operand of comma operator has no effect}} expected-warning {{expression result unused}}
|
||||
foo(),i,j; // expected-warning {{expression result unused}} expected-warning {{left operand of comma operator has no effect}}
|
||||
i,j,foo(); // expected-warning {{expression result unused}} expected-warning {{expression result unused}}
|
||||
i,foo(),j; // expected-warning {{expression result unused}} expected-warning {{expression result unused}}
|
||||
foo(),i,j; // expected-warning {{expression result unused}} expected-warning {{expression result unused}}
|
||||
|
||||
i++;
|
||||
|
||||
i++,foo();
|
||||
foo(),i++;
|
||||
|
||||
i++,j,foo(); // expected-warning {{left operand of comma operator has no effect}}
|
||||
i++,j,foo(); // expected-warning {{expression result unused}}
|
||||
i++,foo(),j; // expected-warning {{expression result unused}}
|
||||
foo(),i++,j; // expected-warning {{expression result unused}}
|
||||
|
||||
i,j++,foo(); // expected-warning {{left operand of comma operator has no effect}}
|
||||
i,foo(),j++; // expected-warning {{left operand of comma operator has no effect}}
|
||||
foo(),i,j++; // expected-warning {{left operand of comma operator has no effect}}
|
||||
i,j++,foo(); // expected-warning {{expression result unused}}
|
||||
i,foo(),j++; // expected-warning {{expression result unused}}
|
||||
foo(),i,j++; // expected-warning {{expression result unused}}
|
||||
|
||||
i++,j++,foo();
|
||||
i++,foo(),j++;
|
||||
|
@ -86,7 +86,7 @@ struct s0 { int f0; };
|
|||
void f0(int a);
|
||||
void f1(struct s0 *a) {
|
||||
// rdar://8139785
|
||||
f0((int)(a->f0 + 1, 10)); // expected-warning {{left operand of comma operator has no effect}}
|
||||
f0((int)(a->f0 + 1, 10)); // expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
void blah(int a);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace test0 {
|
|||
|
||||
template<typename T>
|
||||
struct B {
|
||||
[[clang::annotate("test", ((void)T{}, 9))]] void t() {}
|
||||
[[clang::annotate("test", (T{}, 9))]] void t() {}
|
||||
// expected-error@-1 {{illegal initializer type 'void'}}
|
||||
};
|
||||
B<int> b;
|
||||
|
@ -73,7 +73,7 @@ struct B {
|
|||
[[clang::annotate("jui", b, cf)]] void t2() {}
|
||||
// expected-error@-1 {{'annotate' attribute requires parameter 1 to be a constant expression}}
|
||||
// expected-note@-2 {{is not allowed in a constant expression}}
|
||||
[[clang::annotate("jui", ((void)b, 0), cf)]] [[clang::annotate("jui", &b, cf, &foo::t2, str())]] void t3() {}
|
||||
[[clang::annotate("jui", (b, 0), cf)]] [[clang::annotate("jui", &b, cf, &foo::t2, str())]] void t3() {}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -157,12 +157,12 @@ namespace constexpr_dtor {
|
|||
constexpr ~A() { *p = 0; }
|
||||
};
|
||||
struct Q { int n; constexpr int *get() { return &n; } };
|
||||
static_assert(!__builtin_constant_p(((void)A{}, 123)));
|
||||
static_assert(!__builtin_constant_p((A{}, 123)));
|
||||
// FIXME: We should probably accept this. GCC does.
|
||||
// However, GCC appears to do so by running the destructors at the end of the
|
||||
// enclosing full-expression, which seems broken; running them at the end of
|
||||
// the evaluation of the __builtin_constant_p argument would be more
|
||||
// defensible.
|
||||
static_assert(!__builtin_constant_p(((void)A{Q().get()}, 123)));
|
||||
static_assert(!__builtin_constant_p((A{Q().get()}, 123)));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -745,7 +745,7 @@ namespace dtor {
|
|||
// Ensure that we can handle temporary cleanups for array temporaries.
|
||||
struct ArrElem { constexpr ~ArrElem() {} };
|
||||
using Arr = ArrElem[3];
|
||||
static_assert(((void)Arr{}, true));
|
||||
static_assert((Arr{}, true));
|
||||
}
|
||||
|
||||
namespace dynamic_alloc {
|
||||
|
|
|
@ -88,8 +88,8 @@ enum {
|
|||
|
||||
void diags(int n) {
|
||||
switch (n) {
|
||||
case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} expected-warning {{left operand of comma operator has no effect}}
|
||||
case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} expected-warning {{left operand of comma operator has no effect}}
|
||||
case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
|
||||
case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
|
||||
case __imag(1/0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
|
||||
case (int)__imag((double)(1/0)): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
|
||||
;
|
||||
|
|
|
@ -583,10 +583,10 @@ void expr_comma(int x)
|
|||
|
||||
// Can't use the ASSERT_XXXX macros without adding parens around
|
||||
// the comma expression.
|
||||
static_assert(__is_lvalue_expr((void)x,x), "expected an lvalue");
|
||||
static_assert(__is_rvalue_expr((void)x,1), "expected an rvalue");
|
||||
static_assert(__is_lvalue_expr((void)1,x), "expected an lvalue");
|
||||
static_assert(__is_rvalue_expr((void)1,1), "expected an rvalue");
|
||||
static_assert(__is_lvalue_expr(x,x), "expected an lvalue");
|
||||
static_assert(__is_rvalue_expr(x,1), "expected an rvalue");
|
||||
static_assert(__is_lvalue_expr(1,x), "expected an lvalue");
|
||||
static_assert(__is_rvalue_expr(1,1), "expected an rvalue");
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -179,12 +179,12 @@ void insert(sx5x10_t a, float f) {
|
|||
|
||||
a[4, 5] = 5.0;
|
||||
// expected-error@-1 {{comma expressions are not allowed as indices in matrix subscript expressions}}
|
||||
// expected-warning@-2 {{left operand of comma operator has no effect}}
|
||||
// expected-warning@-2 {{expression result unused}}
|
||||
|
||||
a[4, 5, 4] = 5.0;
|
||||
// expected-error@-1 {{comma expressions are not allowed as indices in matrix subscript expressions}}
|
||||
// expected-warning@-2 {{left operand of comma operator has no effect}}
|
||||
// expected-warning@-3 {{left operand of comma operator has no effect}}
|
||||
// expected-warning@-2 {{expression result unused}}
|
||||
// expected-warning@-3 {{expression result unused}}
|
||||
}
|
||||
|
||||
void extract(sx5x10_t a, float f) {
|
||||
|
|
|
@ -157,7 +157,7 @@ bool& operator,(X, Y);
|
|||
|
||||
void test_comma(X x, Y y) {
|
||||
bool& b1 = (x, y);
|
||||
X& xr = (x, x); // expected-warning {{left operand of comma operator has no effect}}
|
||||
X& xr = (x, x); // expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
struct Callable {
|
||||
|
|
|
@ -85,9 +85,9 @@ void func(int sel) {
|
|||
|
||||
(void)local_int8;
|
||||
|
||||
local_int8, 0; // expected-warning {{left operand of comma operator has no effect}}
|
||||
local_int8, 0; // expected-warning + {{expression result unused}}
|
||||
|
||||
0, local_int8; // expected-warning {{left operand of comma operator has no effect}} expected-warning {{expression result unused}}
|
||||
0, local_int8; // expected-warning + {{expression result unused}}
|
||||
|
||||
svint8_t init_int8 = local_int8;
|
||||
svint8_t bad_init_int8 = for; // expected-error {{expected expression}}
|
||||
|
|
|
@ -381,8 +381,8 @@ void Init() {
|
|||
typedef int inte2 __attribute__((__ext_vector_type__(2)));
|
||||
|
||||
void test_vector_literal(inte4 res) {
|
||||
inte2 a = (inte2)(1, 2); //expected-warning{{left operand of comma operator has no effect}}
|
||||
inte4 b = (inte4)(a, a); //expected-error{{C-style cast from vector 'inte2' (vector of 2 'int' values) to vector 'inte4' (vector of 4 'int' values) of different size}} //expected-warning{{left operand of comma operator has no effect}}
|
||||
inte2 a = (inte2)(1, 2); //expected-warning{{expression result unused}}
|
||||
inte4 b = (inte4)(a, a); //expected-error{{C-style cast from vector 'inte2' (vector of 2 'int' values) to vector 'inte4' (vector of 4 'int' values) of different size}} //expected-warning{{expression result unused}}
|
||||
}
|
||||
|
||||
typedef __attribute__((__ext_vector_type__(4))) float vector_float4;
|
||||
|
|
|
@ -242,8 +242,8 @@ struct bool_seq;
|
|||
|
||||
template <typename... xs>
|
||||
class Foo {
|
||||
typedef bool_seq<((void)xs::value, true)...> all_true;
|
||||
typedef bool_seq<((void)xs::value, false)...> all_false;
|
||||
typedef bool_seq<(xs::value, true)...> all_true;
|
||||
typedef bool_seq<(xs::value, false)...> all_false;
|
||||
typedef bool_seq<xs::value...> seq;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++98 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++11 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++17 %s
|
||||
|
||||
// PR4806
|
||||
namespace test0 {
|
||||
|
@ -139,26 +138,3 @@ void volatile_array() {
|
|||
(void)arr3;
|
||||
(void)arr4;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L // C++11 or later
|
||||
namespace test5 {
|
||||
int v[(5, 6)]; // expected-warning {{left operand of comma operator has no effect}}
|
||||
void foo() {
|
||||
new double[false ? (1, 2) : 3]
|
||||
// FIXME: We shouldn't diagnose the unreachable constant expression
|
||||
// here.
|
||||
[false ? (1, 2) : 3]; // expected-warning {{left operand of comma operator has no effect}}
|
||||
}
|
||||
} // namespace test5
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L // C++17 or later
|
||||
namespace test6 {
|
||||
auto b() {
|
||||
if constexpr (false)
|
||||
return (1,0);
|
||||
else
|
||||
return (1.0,0.0); // expected-warning {{left operand of comma operator has no effect}}
|
||||
}
|
||||
} // namespace test6
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,6 @@ namespace rdar14183893 {
|
|||
|
||||
class A {
|
||||
TFP m_p;
|
||||
void Enable() { 0, A(); } // expected-warning {{left operand of comma operator has no effect}}
|
||||
void Enable() { 0, A(); } // expected-warning {{unused}}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ template void f(int, char, double);
|
|||
namespace PR41576 {
|
||||
template <class... Xs> constexpr int f(Xs ...xs) {
|
||||
return [&](auto ...ys) { // expected-note {{instantiation}}
|
||||
return ((xs + ys), ...); // expected-warning {{left operand of comma operator has no effect}}
|
||||
return ((xs + ys), ...); // expected-warning {{unused}}
|
||||
}(1, 2);
|
||||
}
|
||||
static_assert(f(3, 4) == 6); // expected-note {{instantiation}}
|
||||
|
|
Loading…
Reference in New Issue