aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/class.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-base7.C15
2 files changed, 25 insertions, 3 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 4bffec4..90b3438 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -330,6 +330,15 @@ build_base_path (enum tree_code code,
return error_mark_node;
}
+ bool uneval = (cp_unevaluated_operand != 0
+ || processing_template_decl
+ || in_template_function ());
+
+ /* For a non-pointer simple base reference, express it as a COMPONENT_REF
+ without taking its address (and so causing lambda capture, 91933). */
+ if (code == PLUS_EXPR && !v_binfo && !want_pointer && !has_empty && !uneval)
+ return build_simple_base_path (expr, binfo);
+
if (!want_pointer)
{
rvalue = !lvalue_p (expr);
@@ -357,9 +366,7 @@ build_base_path (enum tree_code code,
template (even in instantiate_non_dependent_expr), we don't have vtables
set up properly yet, and the value doesn't matter there either; we're
just interested in the result of overload resolution. */
- if (cp_unevaluated_operand != 0
- || processing_template_decl
- || in_template_function ())
+ if (uneval)
{
expr = build_nop (ptr_target_type, expr);
goto indout;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-base7.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-base7.C
new file mode 100644
index 0000000..14e026e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-base7.C
@@ -0,0 +1,15 @@
+// PR c++/91933
+// { dg-do compile { target c++11 } }
+
+struct NoMut1 { int a, b; };
+struct NoMut3 : NoMut1 {
+ constexpr NoMut3(int a, int b) : NoMut1{a, b} {}
+};
+void mutable_subobjects() {
+ constexpr NoMut3 nm3 = {1, 2};
+ struct A {
+ void f() {
+ static_assert(nm3.a == 1, "");
+ }
+ };
+}