Author: Akira Hatanaka Date: 2020-05-13T20:12:10-07:00 New Revision: 50a81ea2bce3aec01ae6fae1505e57ec7aa36ac7
URL: https://github.com/llvm/llvm-project/commit/50a81ea2bce3aec01ae6fae1505e57ec7aa36ac7 DIFF: https://github.com/llvm/llvm-project/commit/50a81ea2bce3aec01ae6fae1505e57ec7aa36ac7.diff LOG: Don't apply lvalue-to-rvalue conversion in DefaultLValueConversion to the expression that is passed to it if it has a function type or array type lvalue-to-rvalue conversion should only be applied to non-function, non-array types, but clang was applying the conversion to discarded value expressions of array types. rdar://problem/61203170 Differential Revision: https://reviews.llvm.org/D78134 Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaStmt.cpp clang/test/CXX/expr/p10-0x.cpp clang/test/SemaCXX/warn-unused-value-cxx11.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5adb66dc9ec6..256c0d2b4658 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10855,9 +10855,8 @@ class Sema final { bool Diagnose = true); // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on - // the operand. This is DefaultFunctionArrayLvalueConversion, - // except that it assumes the operand isn't of function or array - // type. + // the operand. This function is a no-op if the operand has a function type + // or an array type. ExprResult DefaultLvalueConversion(Expr *E); // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e8be40c3a92b..93e67ad2940c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -606,6 +606,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { QualType T = E->getType(); assert(!T.isNull() && "r-value conversion on typeless expression?"); + // lvalue-to-rvalue conversion cannot be applied to function or array types. + if (T->isFunctionType() || T->isArrayType()) + return E; + // We don't want to throw lvalue-to-rvalue casts on top of // expressions of certain types in C++. if (getLangOpts().CPlusPlus && diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index f76994a6dab3..0cb600fb46d1 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -370,7 +370,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { } } - if (E->isGLValue() && E->getType().isVolatileQualified()) { + // Tell the user to assign it into a variable to force a volatile load if this + // isn't an array. + if (E->isGLValue() && E->getType().isVolatileQualified() && + !E->getType()->isArrayType()) { Diag(Loc, diag::warn_unused_volatile) << R1 << R2; return; } diff --git a/clang/test/CXX/expr/p10-0x.cpp b/clang/test/CXX/expr/p10-0x.cpp index a42986c85fef..c1b384ad7a51 100644 --- a/clang/test/CXX/expr/p10-0x.cpp +++ b/clang/test/CXX/expr/p10-0x.cpp @@ -44,3 +44,12 @@ void f2(volatile int *x) { refcall(); 1 ? refcall() : *x; } + +// CHECK: define void @_Z2f3v() +// CHECK-NOT: load +// CHECK-NOT: memcpy + +void f3(void) { + volatile char a[10]; + a; +} diff --git a/clang/test/SemaCXX/warn-unused-value-cxx11.cpp b/clang/test/SemaCXX/warn-unused-value-cxx11.cpp index d929b4fd12fb..a6f41c3fd6b3 100644 --- a/clang/test/SemaCXX/warn-unused-value-cxx11.cpp +++ b/clang/test/SemaCXX/warn-unused-value-cxx11.cpp @@ -41,4 +41,13 @@ void j() { (void)noexcept(s.g() = 5); // Ok } -} \ No newline at end of file +} + +namespace volatile_array { +void test() { + char a[10]; + volatile char b[10]; + a; // expected-warning-re {{expression result unused{{$}}}} + b; // expected-warning-re {{expression result unused{{$}}}} +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits