return value_cast_pointers (type, arg, 0);
/* Cast the value to the reference's target type, and then
- convert it back to a reference. This will issue an error
- if the value was not previously in memory - in some cases
- we should clearly be allowing this, but how? */
+ convert it back to a reference. If the value is not already
+ in memory (e.g., a literal), we need to allocate space in the
+ inferior and copy it there. */
new_value = value_cast (type->target_type (), arg);
+ if (new_value->lval () != lval_memory
+ && (language_pass_by_reference (new_value->type ())
+ .trivially_copyable))
+ {
+ LONGEST length = check_typedef (new_value->type ())->length ();
+ struct value *addr_val = value_allocate_space_in_inferior (length);
+ CORE_ADDR addr = value_as_address (addr_val);
+ new_value->force_lval (addr);
+ }
+
new_value = value_ref (new_value, type->code ());
return new_value;
}
return mf1(C);
}
+/* A class to be used by functions and methods exercising c++/25957. */
+class TestClass
+{
+ public:
+ int value;
+
+ TestClass (int v) : value (v) {}
+
+ int
+ const_ref_method (const int &x) const
+ {
+ return value + x;
+ }
+
+ int
+ const_ref_method (const TestClass &obj) const
+ {
+ return value + obj.value;
+ }
+
+ int
+ ref_method (int &x)
+ {
+ return value + 2 * x;
+ }
+
+ int
+ ref_method (TestClass &obj)
+ {
+ return value + 2 * obj.value;
+ }
+};
+
+/* Define globals to be used by functions and methods exercising c++/25957. */
+int global_int = 42;
+TestClass global_obj (10);
+
+/* Helper functions to test reference parameter behavior for c++/25957. */
+int
+const_ref_func (const int &x)
+{
+ return x * 2;
+}
+
+int
+const_ref_func (const TestClass &obj)
+{
+ return obj.value * 2;
+}
+
+int
+ref_func (int &x)
+{
+ return x + 1;
+}
+
+int
+ref_func (TestClass &obj)
+{
+ return obj.value + 1;
+}
+
int main(void)
{
Child Q(42);
mf2(MQ); /* Set breakpoint MQ here. */
- return 0;
+ TestClass obj (5);
+ int local_var = 15;
+
+ /* Prevent compiler from optimizing away the function and method calls. */
+ int dummy_int = 99;
+ (void) const_ref_func (dummy_int);
+ (void) const_ref_func (global_int);
+ (void) const_ref_func (obj);
+ (void) const_ref_func (global_obj);
+ (void) ref_func (dummy_int);
+ (void) ref_func (global_int);
+ (void) ref_func (obj);
+ (void) ref_func (global_obj);
+ (void) obj.const_ref_method (dummy_int);
+ (void) obj.const_ref_method (global_int);
+ (void) obj.const_ref_method (obj);
+ (void) obj.const_ref_method (global_obj);
+ (void) obj.ref_method (dummy_int);
+ (void) obj.ref_method (global_int);
+ (void) obj.ref_method (obj);
+ (void) obj.ref_method (global_obj);
+ (void) global_obj.const_ref_method (dummy_int);
+ (void) global_obj.const_ref_method (global_int);
+ (void) global_obj.const_ref_method (obj);
+ (void) global_obj.const_ref_method (global_obj);
+ (void) global_obj.ref_method (dummy_int);
+ (void) global_obj.ref_method (global_int);
+ (void) global_obj.ref_method (obj);
+ (void) global_obj.ref_method (global_obj);
+
+ /* Breakpoint here for c++/25957 testing. */
+ return 0; /* breakpoint-here */
}
gdb_test "print mf1(MQR)" ".* = 106"
gdb_test "print mf2(MQR)" ".* = 106"
gdb_test "print f3(Q.id)" ".* = 42"
+
+# Inferior function call tests which have reference arguments.
+# https://sourceware.org/bugzilla/show_bug.cgi?id=25957
+gdb_start_again "breakpoint-here"
+
+# Test functions taking const reference parameter.
+gdb_test "print const_ref_func(10)" \
+ "= 20" \
+ "call function with const ref param and literal"
+
+gdb_test "print const_ref_func(global_int)" \
+ "= 84" \
+ "call function with const ref param and global variable"
+
+gdb_test "print const_ref_func(local_var)" \
+ "= 30" \
+ "call function with const ref param and local variable"
+
+gdb_test "print const_ref_func(obj)" \
+ "= 10" \
+ "call function with const ref param and object"
+
+gdb_test "print const_ref_func(global_obj)" \
+ "= 20" \
+ "call function with const ref param and global object"
+
+gdb_test "print const_ref_func((TestClass) {42})" \
+ "= 84" \
+ "call function with const ref param and literal object"
+
+# Test functions taking non-const reference parameter.
+gdb_test "print ref_func(10)" \
+ "Cannot resolve function ref_func to any overloaded instance" \
+ "call function with non-const ref param and literal"
+
+gdb_test "print ref_func(global_int)" \
+ " = 43" \
+ "call function with non-const ref param and global variable"
+
+gdb_test "print ref_func(local_var)" \
+ " = 16" \
+ "call function with non-const ref param and local variable"
+
+gdb_test "print ref_func(obj)" \
+ "= 6" \
+ "call function with non-const ref param and object"
+
+gdb_test "print ref_func(global_obj)" \
+ "= 11" \
+ "call function with non-const ref param and global object"
+
+gdb_test "print ref_func((TestClass) {42})" \
+ "Cannot resolve function ref_func to any overloaded instance" \
+ "call function with ref param and literal object"
+
+# Test methods taking constant reference parameter.
+gdb_test "print obj.const_ref_method(5)" \
+ "= 10" \
+ "call const method with const ref param and literal"
+
+gdb_test "print obj.const_ref_method(global_int)" \
+ "= 47" \
+ "call const method with const ref param and global variable"
+
+gdb_test "print obj.const_ref_method(local_var)" \
+ "= 20" \
+ "call const method with const ref param and local variable"
+
+gdb_test "print obj.const_ref_method(obj)" \
+ "= 10" \
+ "call method with const ref param and object"
+
+gdb_test "print obj.const_ref_method((TestClass) {42})" \
+ "= 47" \
+ "call method with const ref param and literal object"
+
+# Test methods taking non-const reference parameters.
+gdb_test "print obj.ref_method(5)" \
+ "Cannot resolve method TestClass::ref_method to any overloaded instance" \
+ "call method with non-const ref param and literal"
+
+gdb_test "print obj.ref_method(global_int)" \
+ "= 89" \
+ "cal method with non-const ref param and global variable"
+
+gdb_test "print obj.ref_method(local_var)" \
+ " = 35" \
+ "call method with non-const ref param and local variable"
+
+gdb_test "print obj.ref_method(obj)" \
+ "= 15" \
+ "call method with non-const ref param and object"
+
+gdb_test "print obj.ref_method((TestClass) {42})" \
+ "Cannot resolve method TestClass::ref_method to any overloaded instance" \
+ "call method with non-const ref param and literal object"
+
+# Test global_obj methods taking constant reference parameter.
+gdb_test "print global_obj.const_ref_method(5)" \
+ "= 15" \
+ "call global const method with const ref param and literal"
+
+gdb_test "print global_obj.const_ref_method(global_int)" \
+ "= 52" \
+ "call global const method with const ref param and global variable"
+
+gdb_test "print global_obj.const_ref_method(local_var)" \
+ "= 25" \
+ "call global const method with const ref param and local variable"
+
+gdb_test "print global_obj.const_ref_method(obj)" \
+ "= 15" \
+ "call global method with const ref param and object"
+
+gdb_test "print global_obj.const_ref_method(global_obj)" \
+ "= 20" \
+ "call global method with const ref param and global object"
+
+gdb_test "print global_obj.const_ref_method((TestClass) {42})" \
+ "= 52" \
+ "call global method with const ref param and literal object"
+
+# Test global_obj methods taking non-const reference parameters.
+gdb_test "print global_obj.ref_method(5)" \
+ "Cannot resolve method TestClass::ref_method to any overloaded instance" \
+ "call global method with non-const ref param and literal"
+
+gdb_test "print global_obj.ref_method(global_int)" \
+ "= 94" \
+ "call global method with non-const ref param and global variable"
+
+gdb_test "print global_obj.ref_method(local_var)" \
+ "= 40" \
+ "call global method with non-const ref param and local variable"
+
+gdb_test "print global_obj.ref_method(obj)" \
+ "= 20" \
+ "call global method with non-const ref param and object"
+
+gdb_test "print global_obj.ref_method(global_obj)" \
+ "= 30" \
+ "call global method with non-const ref param and global object"
+
+gdb_test "print global_obj.ref_method ((TestClass) {42})" \
+ "Cannot resolve method TestClass::ref_method to any overloaded instance" \
+ "call global method with non-const ref param and literal object"