@@ -22247,6 +22247,7 @@ gen_variable_die (tree decl, tree origin
tree ultimate_origin;
dw_die_ref var_die;
dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
+ dw_die_ref origin_die = NULL;
bool declaration = (DECL_EXTERNAL (decl_or_origin)
|| class_or_namespace_scope_p (context_die));
bool specialization_p = false;
@@ -22413,7 +22414,7 @@ gen_variable_die (tree decl, tree origin
var_die = new_die (tag, context_die, decl);
if (origin != NULL)
- add_abstract_origin_attribute (var_die, origin);
+ origin_die = add_abstract_origin_attribute (var_die, origin);
/* Loop unrolling can create multiple blocks that refer to the same
static variable, so we must test for the DW_AT_declaration flag.
@@ -21513,6 +21513,14 @@ gen_variable_die (tree decl, tree origin
}
else
tree_add_const_value_attribute_for_decl (var_die, decl_or_origin);
+
+ if ((dwarf_version >= 4 || !dwarf_strict)
+ && lang_hooks.decls.decl_dwarf_attribute (decl_or_origin,
+ DW_AT_const_expr) == 1
+ && !get_AT (var_die, DW_AT_const_expr)
+ && (origin_die == NULL || get_AT (origin_die, DW_AT_const_expr) == NULL)
+ && !specialization_p)
+ add_AT_flag (var_die, DW_AT_const_expr, 1);
}
/* Generate a DIE to represent a named constant. */
@@ -168,6 +168,11 @@ cp_decl_dwarf_attribute (const_tree decl
}
break;
+ case DW_AT_const_expr:
+ if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
+ return 1;
+ break;
+
default:
break;
}
@@ -0,0 +1,9 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" }
+// { dg-final { scan-assembler-times " DW_AT_const_expr" 2 } }
+
+constexpr int a = 5;
+struct S
+{
+ static constexpr int b = 6;
+} s;