[PATCH] D78134: [Sema] Don't apply an lvalue-to-rvalue conversion to a discarded-value expression if it has an array type
Akira Hatanaka via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 14 11:16:22 PDT 2020
ahatanak created this revision.
ahatanak added reviewers: efriedma, rsmith, rjmccall.
ahatanak added a project: clang.
Herald added subscribers: ributzka, dexonsmith, jkorous.
This fixes a bug which causes clang to emit incorrect IR for the following code in C++:
int foo(void) {
unsigned a = get_size();
volatile char b[a];
b;
return b[0];
}
The code crashes because the destination of the memcpy that is generated to do the lvalue-to-rvalue conversion of discarded-value expression `b` is incorrect. To fix this bug, I've added a check to Sema which prevents an lvalue cast expression to be emitted if the expression has an array type. My understanding is that lvalue-to-rvalue conversion isn't applied to array type expressions, so I think we should detect this in Sema rather than fixing the code in IRGen that emits the lvalue for the destination of the lvalue-to-rvalue conversion. I've also made changes to `Sema::DiagnoseUnusedExprResult` so that clang doesn't tell users to assign a reference to a volatile array to a variable to force its value to be loaded.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D78134
Files:
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaStmt.cpp
clang/test/CXX/expr/p10-0x.cpp
clang/test/SemaCXX/warn-unused-value-cxx11.cpp
Index: clang/test/SemaCXX/warn-unused-value-cxx11.cpp
===================================================================
--- clang/test/SemaCXX/warn-unused-value-cxx11.cpp
+++ 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{{$}}}}
+}
+}
Index: clang/test/CXX/expr/p10-0x.cpp
===================================================================
--- clang/test/CXX/expr/p10-0x.cpp
+++ 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;
+}
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ 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;
}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7756,11 +7756,15 @@
// conversion.
if (getLangOpts().CPlusPlus11 && E->isGLValue() &&
E->getType().isVolatileQualified()) {
- if (IsSpecialDiscardedValue(E)) {
- ExprResult Res = DefaultLvalueConversion(E);
- if (Res.isInvalid())
- return E;
- E = Res.get();
+ if (IsSpecialDiscardedValue(E)) {
+ // Don't try to apply lvalue-to-rvalue conversion to expressions of
+ // array types.
+ if (!E->getType()->isArrayType()) {
+ ExprResult Res = DefaultLvalueConversion(E);
+ if (Res.isInvalid())
+ return E;
+ E = Res.get();
+ }
} else {
// Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if
// it occurs as a discarded-value expression.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78134.257402.patch
Type: text/x-patch
Size: 2423 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200414/ba33c490/attachment.bin>
More information about the cfe-commits
mailing list