diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10855,9 +10855,8 @@ 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 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -606,6 +606,10 @@ 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 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -370,7 +370,10 @@ } } - 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 --- a/clang/test/CXX/expr/p10-0x.cpp +++ b/clang/test/CXX/expr/p10-0x.cpp @@ -44,3 +44,12 @@ 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 --- a/clang/test/SemaCXX/warn-unused-value-cxx11.cpp +++ b/clang/test/SemaCXX/warn-unused-value-cxx11.cpp @@ -41,4 +41,13 @@ (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{{$}}}} +} +}