diff options
Diffstat (limited to 'gdb/testsuite/gdb.compile')
25 files changed, 2980 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.compile/compile-cplus-mod.c b/gdb/testsuite/gdb.compile/compile-cplus-mod.c new file mode 100644 index 00000000000..8b7c75576a5 --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-cplus-mod.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014-2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +extern "C" void +_gdb_expr (void) +{ + // Make 'globalvar' lookup working. +#pragma GCC push_user_expression + + globalvar = 3; + globalvar += 4; + +#pragma GCC pop_user_expression +} diff --git a/gdb/testsuite/gdb.compile/compile-cplus-print.c b/gdb/testsuite/gdb.compile/compile-cplus-print.c new file mode 100644 index 00000000000..2635d16796f --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-cplus-print.c @@ -0,0 +1,32 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015-2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +int varint = 10; +int vararray[] = { 1, 2, 3, 4, 5 }; +int *vararrayp = vararray; +struct object +{ + int field; +} varobject = { 1 }; + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.compile/compile-cplus-print.exp b/gdb/testsuite/gdb.compile/compile-cplus-print.exp new file mode 100644 index 00000000000..cb453a4e184 --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-cplus-print.exp @@ -0,0 +1,75 @@ +# Copyright 2015-2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib compile-support.exp + +standard_testfile + +get_compiler_info +set options {} +if [test_compiler_info gcc*] { + lappend options additional_flags=-g3 + lappend options additional_flags=-std=gnu++11 + lappend options c++ +} + +set srcfilesoptions [list ${srcfile} ${options}] + +if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } { + return -1 +} + +clean_restart ${testfile} + +if {[skip_compile_feature_tests]} { + untested "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_test_no_output "set language c++" \ + "Set language to C++" + +if ![runto_main] { + return -1 +} + +gdb_test "compile print varint" " = 10" +gdb_test "compile print vararray" " = \\{1, 2, 3, 4, 5\\}" +gdb_test "compile print main" " = \\{int \\(void\\)\\} 0x\[0-9a-f\]+" + +set test "compile print *vararray@3" +gdb_test_multiple $test $test { + -re " = \\{1, 2, 3\\}\r\n$gdb_prompt $" { + pass $test + } + -re ": error: stray '@' in program\r\n.*\r\n$gdb_prompt $" { + kfail compile/18489 "$test" + } +} + +set test "compile print *vararrayp@3" +gdb_test_multiple $test $test { + -re " = \\{1, 2, 3\\}\r\n$gdb_prompt $" { + pass $test + } + -re ": error: stray '@' in program\r\n.*\r\n$gdb_prompt $" { + kfail compile/18489 "$test" + } +} + +gdb_test "compile print/x 256" " = 0x100" +gdb_test {print $} " = 256" + +gdb_test "compile print varobject" { = {field = 1}} diff --git a/gdb/testsuite/gdb.compile/compile-cplus.c b/gdb/testsuite/gdb.compile/compile-cplus.c new file mode 100644 index 00000000000..3ba46ce947d --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-cplus.c @@ -0,0 +1,241 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014-2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <stdbool.h> +#include <iostream> + +#define SOME_MACRO 23 +#define ARG_MACRO(X, Y) ((X) + (Y) - 1) + + +enum enum_type { + ONE = 1, + TWO = 2 +}; + +typedef int v4 __attribute__ ((vector_size (16))); + +union union_type; + +struct struct_type { + char charfield; + unsigned char ucharfield; + short shortfield; + unsigned short ushortfield; + int intfield; + unsigned int uintfield; + unsigned int bitfield : 3; + long longfield; + unsigned long ulongfield; + enum enum_type enumfield; + float floatfield; + double doublefield; + const union union_type *ptrfield; + struct struct_type *selffield; + int arrayfield[5]; + _Complex double complexfield; + _Bool boolfield; + v4 vectorfield; +}; + +typedef int inttypedef; + +union union_type { + int intfield; + inttypedef typedeffield; +}; + +/* volatile provides some coverage of the conversion code. */ +volatile struct struct_type struct_object; + +union union_type union_object; + + +enum ulonger_enum_type { + REALLY_MINUS_1 = -1UL, +}; + +enum ulonger_enum_type ulonger; + +enum longer_enum_type { + MINUS_1 = -1, + FORCE_TO_LONG = 1L << ((8 * sizeof (long)) - 2) +}; + +enum longer_enum_type longer; + +int globalvar = 10; + +static void +func_static (int addend) +{ + globalvar += addend; +} + +void +func_global (int subtrahend) +{ + globalvar -= subtrahend; +} + +void +no_args_or_locals (void) +{ + /* no_args_or_locals breakpoint */ +} + +int *intptr; +int globalshadow = 10; +static int staticshadow = 20; +int externed = 7; + +class Base +{ + virtual int pure_virt () = 0; + public: + int return_value () {return a;} + private: + int a = 1; + int b = 2; +}; + +class Base2 +{ + virtual int non_pure () {return 84;} + public: + int return_value () {return b;} + private: + int a = 3; + int b = 4; +}; + +class Base3 +{ + public: + int return_value () {return b;} + private: + int b = 5; +}; + + +class Multiple : public Base, public Base2 +{ + int pure_virt () + { + int a = Base::return_value (); + return a + 42; + } +}; +//struct foo { foo(); virtual ~foo(); }; struct bar : virtual foo { bar(); ~bar(); }; struct baz : bar {}; bar::bar() {} bar::~bar() {} bar t; baz u; +struct VirtualOnly +{ + VirtualOnly(); + virtual ~VirtualOnly()=0; +}; + +VirtualOnly::VirtualOnly () +{ +} + +VirtualOnly::~VirtualOnly () +{ +} + +struct VirtualBase : virtual VirtualOnly +{ + int z = 22; + VirtualBase (void); + ~VirtualBase (void); +}; + +struct VirtualBase2 : VirtualBase {}; + +VirtualBase::VirtualBase (void) +{ + z = 24; +} + +VirtualBase::~VirtualBase (void) +{ + z = 22; +} + +class Foo +{ + int var; + static const int public_static_var = 12; + + private: + int private_var = 0; + int private_method (void); + + public: + int public_var = 0; + int public_method (void); + void set_private_var (int); +}; + +void Foo::set_private_var (int i) +{ + private_var = i; +} + +int Foo::private_method (void) +{ + return private_var; +} + +int Foo::public_method (void) +{ + return public_var; +} + +int +main (void) +{ + int localvar = 50; + int shadowed = 51; + int bound = 3; + int unresolved = 10; + int globalshadow = 100; + int staticshadow = 200; + int externed = 9; + int f = 0; + int var = 0; + Foo foovar; + Multiple *multivar = new Multiple; + VirtualBase vbase; + VirtualBase2 vbase2; + static int static_local = 77000; + + foovar.public_var = 42; + foovar.set_private_var (42); + multivar->Base2::return_value(); + { + int another_local = 7; + int shadowed = 52; + extern int unresolved; + extern int externed; + + int vla[bound]; + + func_static (0); /* break-here */ + no_args_or_locals (); + } + + return 0; +} diff --git a/gdb/testsuite/gdb.compile/compile-cplus.exp b/gdb/testsuite/gdb.compile/compile-cplus.exp new file mode 100644 index 00000000000..04849ba3947 --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-cplus.exp @@ -0,0 +1,341 @@ +# Copyright 2014-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib compile-support.exp + +standard_testfile .c compile-shlib.c compile-constvar.S compile-nodebug.c + +get_compiler_info +set options {} +if [test_compiler_info gcc*] { + lappend options additional_flags=-g3 + lappend options additional_flags=-std=gnu++11 + lappend options c++ +} + +if { ![istarget x86_64-*-* ] || ![is_lp64_target] } { + verbose "Skipping x86_64 LOC_CONST test." + set srcfile3 "" +} + +set srcfilesoptions [list ${srcfile} ${options}] +if { $srcfile3 != "" } { + lappend srcfilesoptions $srcfile3 ${options} +} +lappend srcfilesoptions $srcfile4 "nodebug c++" +if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } { + return -1 +} + +clean_restart ${testfile} + +# +# FIXME: Right now, for C++ we just duplicate the C tests, but force +# the language to C++ +# +gdb_test_no_output "set language c++" \ + "Set language to C++" + +if ![runto_main] { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +# +# Test delimiter for code, and arguments. +# + + +gdb_test_no_output "compile code globalvar = SOME_MACRO;" \ + "set variable from macro" +gdb_test "p globalvar" " = 23" "expect 23" + +gdb_test_no_output "compile code globalvar = ARG_MACRO(0, 0);" \ + "set variable from function-like macro" +gdb_test "p globalvar" " = -1" "expect -1" + +gdb_test_no_output "compile code globalvar = 42;" "set variable" +gdb_test "p globalvar" " = 42" "expect 42" + +gdb_test_no_output "compile code globalvar *= 2;" "modify variable" +gdb_test "p globalvar" " = 84" "expect 84" + +gdb_test_no_output "compile file -r ${srcdir}/${subdir}/${testfile}-mod.c" \ + "use external source file" +gdb_test "p globalvar" " = 7" "expect 7" + +gdb_test_no_output "compile code func_static (2);" "call static function" +gdb_test "p globalvar" " = 9" "expect 9" +gdb_test_no_output "compile code func_global (1);" "call global function" +gdb_test "p globalvar" " = 8" "expect 8" + +gdb_test_no_output \ + "compile code globalvar = (sizeof (ulonger) == sizeof (long))" \ + "compute size of ulonger" +gdb_test "p globalvar" " = 1" "check size of ulonger" +gdb_test_no_output \ + "compile code globalvar = (sizeof (longer) == sizeof (long))" \ + "compute size of longer" +gdb_test "p globalvar" " = 1" "check size of longer" +gdb_test_no_output "compile code globalvar = MINUS_1" +gdb_test "p globalvar" " = -1" "check MINUS_1" + +gdb_test_no_output "compile code globalvar = static_local" +gdb_test "p globalvar" " = 77000" "check static_local" + +gdb_test_no_output \ + "compile code static int staticvar = 5; intptr = &staticvar" \ + "do not keep jit in memory" +gdb_test "p *intptr" "Cannot access memory at address 0x\[0-9a-f\]+" \ + "expect 5" + +gdb_test "compile code func_doesnotexist ();" "error: \'func_doesnotexist\' was not declared in this scope.*" + +gdb_test "compile code *(volatile int *) 0 = 0;" \ + "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB remains in the frame where the signal was received\\.\r\n.*" \ + "compile code segfault first" +gdb_test "bt" \ + "\r\n#0 \[^\r\n\]* in _gdb_expr \[^\r\n\]*\r\n#1 <function called from gdb>\r\n.*" + +set test "p/x \$pc" +set infcall_pc 0 +gdb_test_multiple $test $test { + -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { + set infcall_pc $expect_out(1,string) + pass $test + } +} + +gdb_test "info sym $infcall_pc" "\r\n_gdb_expr.*" "info sym found" +gdb_test "return" "\r\n#0 main .*" "return" \ + "Make _gdb_expr\\(__gdb_regs\\*\\) return now\\? \\(y or n\\) " "y" +gdb_test "info sym $infcall_pc" "\r\nNo symbol matches .*" "info sym not found" + +gdb_test_no_output "set unwindonsignal on" +gdb_test "compile code *(volatile int *) 0 = 0;" \ + "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB has restored the context to what it was before the call\\.\r\n.*" \ + "compile code segfault second" + +gdb_breakpoint [gdb_get_line_number "break-here"] +gdb_continue_to_breakpoint "break-here" ".* break-here .*" + +# C++ Specific tests. +## Public methods and members + +gdb_test "print foovar.public_var" "42" \ + "Test compile code foovar.public_var = 42 setting." +gdb_test_no_output "compile code foovar.public_var = 43;" \ + "set foobar.public_var to 43" +gdb_test "print foovar.public_var" "43" \ + "Test compile code foovar.public_var = 43 setting." +gdb_test "print foovar.public_method ()" "43" \ + "Test compile code foovar.public_method = 43 setting." + +## Private methods and members +gdb_test_no_output "compile code foovar.set_private_var (84);" \ + "Call class function to set private_var" +gdb_test "print foovar.private_var" "84" \ + "Test compile code foovar.set_private_var = 84 setting." +gdb_test_no_output "compile code foovar.private_var = 85" \ + "Directly set a private member in GDB compile5" +gdb_test "print foovar.private_var" "85" \ + "Test compile code foovar.set_private_var = 85 setting." + +## Simple inheritance +CompileExpression::new "var" +CompileExpression::test "class Baz: public Foo {public: int z = 12;}; Baz bazvar; bazvar.z = 24; var = bazvar.z" 24 -explicit +## Multiple inheritance +CompileExpression::test "class MI: public Base, public Base2 {int pure_virt () {return 42;}}; MI MIVar; var = MIVar.pure_virt();" 42 -explicit +CompileExpression::test "class MI: public Base, public Base2 {int pure_virt () {return Base::return_value() + 42;}}; MI MIVar; var = MIVar.pure_virt();" 43 -explicit +CompileExpression::test "class Base3 {public: int z = 99;}; class MI: public Base, public Base3 {int pure_virt () {return Base3::z + 42;}}; MI MIVar; var = MIVar.pure_virt();" 141 -explicit + +gdb_test "p localvar" " = 50" "expect localvar 50" + +gdb_test_no_output "compile code localvar = 12;" "set localvar" +gdb_test "p localvar" " = 12" "expect 12" + +gdb_test_no_output "compile code localvar *= 2;" "modify localvar" +gdb_test "p localvar" " = 24" "expect 24" + +gdb_test_no_output "compile code localvar = shadowed" \ + "test shadowing" +gdb_test "p localvar" " = 52" "expect 52" + +gdb_test_no_output "compile code localvar = externed" +gdb_test "p localvar" " = 7" "test extern in inner scope" + +gdb_test_no_output "compile code vla\[2\] = 7" +gdb_test "p vla\[2\]" " = 7" +gdb_test_no_output \ + "compile code localvar = (sizeof (vla) == bound * sizeof (vla\[0\]))" +gdb_test "p localvar" " = 1" + +# +# Test setting fields and also many different types. +# + +gdb_test_no_output "compile code struct_object.selffield = (struct_type*)&struct_object" +gdb_test "print struct_object.selffield == &struct_object" " = true" + +gdb_test_no_output "compile code struct_object.charfield = 1" +gdb_test "print struct_object.charfield" " = 1 '\\\\001'" +gdb_test_no_output "compile code struct_object.ucharfield = 1" +gdb_test "print struct_object.ucharfield" " = 1 '\\\\001'" + +foreach {field value} { + shortfield -5 + ushortfield 5 + intfield -7 + uintfield 7 + bitfield 2 + longfield -9 + ulongfield 9 + enumfield ONE + floatfield 1 + doublefield 2 +} { + gdb_test_no_output "compile code struct_object.$field = $value" + gdb_test "print struct_object.$field" " = $value" +} + +gdb_test_no_output "compile code struct_object.arrayfield\[2\] = 7" +gdb_test "print struct_object.arrayfield" \ + " = \\{0, 0, 7, 0, 0\\}" + +gdb_test_no_output "compile code struct_object.complexfield = 7 + 5i" +gdb_test "print struct_object.complexfield" " = 7 \\+ 5 \\* I" + +gdb_test_no_output "compile code struct_object.boolfield = 1" +gdb_test "print struct_object.boolfield" " = true" + +gdb_test_no_output "compile code struct_object.vectorfield\[2\] = 7" +gdb_test "print struct_object.vectorfield" \ + " = \\{0, 0, 7, 0\\}" + +gdb_test_no_output "compile code union_object.typedeffield = 7" +gdb_test "print union_object.typedeffield" " = 7" +gdb_test "print union_object.intfield" " = 7" + + +# LOC_UNRESOLVED tests. + +gdb_test "print unresolved" " = 20" +gdb_test "compile code globalvar = unresolved;" +gdb_test "print globalvar" " = 20" "print unresolved value" + +# Test shadowing with global and static variables. + +gdb_test_no_output "compile code globalshadow += 1;" +gdb_test "print globalshadow" " = 101" +gdb_test_no_output "compile code extern int globalshadow; globalshadow += 5;" +gdb_test "print 'compile-cplus.c'::globalshadow" " = 15" +gdb_test "print globalshadow" " = 101" "print globalshadow second time" +gdb_test_no_output "compile code staticshadow += 2;" +gdb_test "print staticshadow" " = 202" +# "extern int staticshadow;" cannot access static variable. + +# Raw code cannot refer to locals. +# As it references global variable we need the #pragma. +# For #pragma we need multiline input. +gdb_test_multiple "compile code -r" "compile code -r multiline 1" { -re "\r\n>$" {} } +gdb_test_multiple "void _gdb_expr(void) {" "compile code -r multiline 2" { -re "\r\n>$" {} } +gdb_test_multiple "#pragma GCC push_user_expression" "compile code -r multiline 3" { -re "\r\n>$" {} } +gdb_test_multiple " globalshadow = 77000;" "compile code -r multiline 4" { -re "\r\n>$" {} } +gdb_test_multiple "#pragma GCC pop_user_expression" "compile code -r multiline 5" { -re "\r\n>$" {} } +gdb_test_multiple "}" "compile code -r multiline 6" { -re "\r\n>$" {} } +gdb_test_no_output "end" "compile code -r multiline 7" +gdb_test "print 'compile-cplus.c'::globalshadow" " = 77000" \ + "check globalshadow with -r" + +# Test GOT vs. resolving jit function pointers. + +gdb_test_no_output "compile -raw -- extern \"C\" void abort(); int func(){return 21;} void _gdb_expr(){int (*funcp)()=func; if (funcp()!=21) abort();}" \ + "pointer to jit function" + +# +# Test the case where the registers structure would not normally have +# any fields. +# + +gdb_breakpoint [gdb_get_line_number "no_args_or_locals breakpoint"] +gdb_continue_to_breakpoint "no_args_or_locals" + +gdb_test_no_output "compile code globalvar = 77;" "set variable to 77" +gdb_test "p globalvar" " = 77" "expect 77" + + +# Test reference to minimal_symbol, not (full) symbol. + +gdb_test_no_output "compile code globalvar = func_nodebug (75);" \ + "call func_nodebug" +gdb_test "p globalvar" " = -75" "expect -75" +gdb_test_no_output \ + "compile code int (*funcp) (int) = (int(*)(int))func_nodebug; globalvar = funcp (76);" \ + "call func_nodebug indirectly" +gdb_test "p globalvar" " = -76" "expect -76" + + +# Test compiled module memory protection. + +gdb_test_no_output "set debug compile on" +gdb_test "compile code static const int readonly = 1; *(int *) &readonly = 2;" \ + "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB has restored the context to what it was before the call\\.\r\n.*" +gdb_test_no_output "set debug compile off" + + +# +# Some simple coverage tests. +# + +gdb_test "show debug compile" "Compile debugging is .*" +gdb_test "show compile-args" \ + "Compile command command-line arguments are .*" +gdb_test "compile code -z" "Unknown argument.*" + +gdb_test "set lang rust" \ + "Warning: the current language does not match this frame." +gdb_test "compile code globalvar" "No compiler support for language rust\." +gdb_test_no_output "set lang auto" + +gdb_test_no_output "compile code union union_type newdecl_u" +gdb_test_no_output "compile code struct struct_type newdecl_s" +gdb_test_no_output "compile code inttypedef newdecl_i" + +gdb_test "compile file" \ + "You must provide a filename for this command.*" \ + "Test compile file without a filename" +gdb_test "compile file -r" \ + "You must provide a filename with the raw option set.*" \ + "Test compile file and raw option without a filename" +gdb_test "compile file -z" \ + "Unknown argument.*" \ + "Test compile file with unknown argument" + + +# LOC_CONST tests. + +if { $srcfile3 != "" } { + gdb_test "p constvar" " = 3" + gdb_test "info addr constvar" {Symbol "constvar" is constant\.} + + gdb_test "compile code globalvar = constvar;" + gdb_test "print globalvar" " = 3" "print constvar value" +} else { + untested "print constvar value" +} diff --git a/gdb/testsuite/gdb.compile/cp-namespace-template.cc b/gdb/testsuite/gdb.compile/cp-namespace-template.cc new file mode 100644 index 00000000000..18bbab4d666 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-namespace-template.cc @@ -0,0 +1,138 @@ +/* Copyright 2016-2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +namespace N1 +{ + namespace N2 + { + template <typename T, int V> + T mytemplate (int a) + { + return static_cast<T> (a) + V; + } + + template <typename T, int V> + T mytemplate (void) + { + return -V; + } + + template <int V = 100> + int mytemplate (void) + { + return V; + } + + struct A + { + A (int val) : value (val) { } + operator int () const { return value; } + + template <typename T = A> + T tempmethod (void) + { + return value; + } + + template <typename T = A, int V = -1> + static T stempmethod (void) + { + return V; + } + + template <typename T = A, int V = -2> + static T stempmethod (T arg) + { + return arg + V; + } + + int value; + }; + + template<> + int + A::tempmethod (void) + { + return -value; + } + + // A handful of operator templates + struct O + { + O (int v) : v_ (v) { } + + template <typename T> + operator T (void) { return -v_; } + + template <typename T> + O operator+ (T val) + { + return v_ + val; + } + + int v_; + }; + + // A simple class template + template <typename T1 = O, typename T2 = int, int V = 3> + class classt + { + public: + classt (T1 v) : val1_ (v), val2_ (107) { } + T1 get1 (void) const { return val1_; } + T2 get2 (void) const { return val2_; } + int get3 (void) const { return V; } + + private: + T1 val1_; + T2 val2_; + }; + }; +}; + +int +main (void) +{ + using namespace N1::N2; + + A a (20); + O o (30); + int var = 0xdeadbeef; + int i = 1; + const int j = 1; + int* pi = &i; + int const* const cpci = &j; + int *const cpi = &i; + + int o_val = o + 30; + + classt<> cddd (o); + classt<int> cdd (100); + classt<int, char> cd (101); + classt<int, char, 12> c (102); + int cvals = cddd.get1 () + cddd.get2 () + cddd.get3 (); + cvals += cdd.get1 () + cdd.get2 () + cdd.get3 (); + cvals += cd.get1 () + cd.get2 () + cd.get3 (); + cvals += c.get1 () + c.get2 () + c.get3 (); + + return mytemplate<int, 1> (0) + + mytemplate<int, 1> () + + mytemplate<0> () + + mytemplate () + + a.tempmethod () + + a.tempmethod<int> () + + A::stempmethod () + + A::stempmethod (0); // break here +} diff --git a/gdb/testsuite/gdb.compile/cp-namespace-template.exp b/gdb/testsuite/gdb.compile/cp-namespace-template.exp new file mode 100644 index 00000000000..19eabe97595 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-namespace-template.exp @@ -0,0 +1,67 @@ +# Copyright 2016-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Namespace-qualified template tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "N1::N2::mytemplate<int, 1> ()" -1 +CompileExpression::test "N1::N2::mytemplate<int, 1> (1)" 2 +CompileExpression::test "N1::N2::mytemplate<0> ()" 0 +CompileExpression::test "N1::N2::mytemplate ()" 100 +CompileExpression::test "a.tempmethod ()" {(20|{value = 20})} \ + -print {xfail *-*-* gcc/debug/49348} \ + -value {xfail *-*-* gcc/debug/49348} +CompileExpression::test "a.tempmethod<N1::N2::A> ()" {(20|{value = 20})} +CompileExpression::test "a.tempmethod<int> ()" -20 +CompileExpression::test "o + 3" {(-33|{v_ = 33})} +CompileExpression::test "cddd.get1 ()" {(-30|{v_ = 30})} +CompileExpression::test "cddd.get2 ()" 107 +CompileExpression::test "cddd.get3 ()" 3 +CompileExpression::test "cdd.get1 ()" 100 +CompileExpression::test "cdd.get2 ()" 107 +CompileExpression::test "cdd.get3 ()" 3 +CompileExpression::test "cd.get1 ()" 101 +CompileExpression::test "cd.get2 ()" {107( 'k')?} +CompileExpression::test "cd.get3 ()" 3 +CompileExpression::test "c.get1 ()" 102 +CompileExpression::test "c.get2 ()" {107( 'k')?} +CompileExpression::test "c.get3 ()" 12 diff --git a/gdb/testsuite/gdb.compile/cp-simple-anonymous.cc b/gdb/testsuite/gdb.compile/cp-simple-anonymous.cc new file mode 100644 index 00000000000..19b9fc85b7b --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-anonymous.cc @@ -0,0 +1,65 @@ +/* Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +static enum {ABC = 1, DEF, GHI, JKL} anon_e = GHI; +static union +{ + char aa; + int bb; + float ff; + double dd; + void *pp; +} anon_u = { 'a' }; + +static struct +{ + char *ptr; + int len; +} anon_s = {"abracadabra", 11}; + +struct A +{ + A (void) : e (AA) + { + this->u.b = 0; + this->s.ptr = "hello"; + this->s.len = 5; + } + + enum {AA = 10, BB, CC, DD} e; + union + { + char a; + int b; + float f; + double d; + void *p; + } u; + struct + { + char *ptr; + int len; + } s; +}; + +int +main (void) +{ + A a; + int var = 1234; + + return a.u.b + a.s.len + static_cast<int> (a.e) + + static_cast<int> (anon_e) + anon_u.bb + anon_s.len; // break here +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-anonymous.exp b/gdb/testsuite/gdb.compile/cp-simple-anonymous.exp new file mode 100644 index 00000000000..094c07be0c8 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-anonymous.exp @@ -0,0 +1,55 @@ +# Copyright 2015-2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple method tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +# Reminder, "var" is an integer; all these types get converted to `int'. +CompileExpression::new "var" +CompileExpression::test "anon_e" {(3|GHI)} +CompileExpression::test "anon_u.aa" {97( 'a')?} +CompileExpression::test "anon_s.len" 11 +CompileExpression::test "a.u.b" 0 +CompileExpression::test "a.s.len" 5 +CompileExpression::test "a.e" {(10|A::AA)} +CompileExpression::test "(*anon_s.ptr == 'a')" (1|true) +CompileExpression::test "(*a.s.ptr != 'h')" (0|false) +CompileExpression::test "A::BB" {(11|A::BB)} diff --git a/gdb/testsuite/gdb.compile/cp-simple-inherit.cc b/gdb/testsuite/gdb.compile/cp-simple-inherit.cc new file mode 100644 index 00000000000..3e445dffc34 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-inherit.cc @@ -0,0 +1,58 @@ +/* Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +struct A +{ + A () : a_ (1) {} + int do_it (int amount) { return a_ + amount; } + + int a_; +}; + +struct B +{ + B () : b_ (2) {} + int do_it (int amount) { return b_ - amount; } + + int b_; +}; + +struct C +{ + C () : c_ (3) {} + int do_it (int amount) { return c_ * amount; } + + int c_; +}; + +struct D : public A, B, C +{ + D () : d_ (4) {} + + int d_; +}; + +int +main (void) +{ + D d; + int var = 1234; + + var = d.A::do_it (1) + + d.B::do_it (2) + + d.C::do_it (3); // break here + + return 0; +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-inherit.exp b/gdb/testsuite/gdb.compile/cp-simple-inherit.exp new file mode 100644 index 00000000000..64c89064269 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-inherit.exp @@ -0,0 +1,52 @@ +# Copyright 2015, 2016, 2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple inheritance tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "d.a_" 1 +CompileExpression::test "d.b_" 2 +CompileExpression::test "d.c_" 3 +CompileExpression::test "d.d_" 4 +CompileExpression::test "d.A::do_it (1)" 2 +CompileExpression::test "d.B::do_it (1)" 1 +CompileExpression::test "d.C::do_it (1)" 3 diff --git a/gdb/testsuite/gdb.compile/cp-simple-member.cc b/gdb/testsuite/gdb.compile/cp-simple-member.cc new file mode 100644 index 00000000000..9278088468c --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-member.cc @@ -0,0 +1,83 @@ +/* Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +class A; +static int get_values (const A& a); + +enum myenum {E_A = 10, E_B, E_C, E_D, E_E}; + +#if WE_DONT_LIKE_THIS +// Yet? GCC outputs DW_AT_linkage_name="<anon>" +// This *really* messes things up. +namespace { + typedef enum {AA = 20, AB, AC, AD} ANON_E; +} +#endif + +namespace N { + typedef enum {AA = 20, AB, AC, AD} ANON_E; +} + +class A +{ +public: + typedef int ATYPE; + + A(void) : public_ (1), protected_ (N::AB), private_ (3) {} + ATYPE public_; + static const myenum s_public_; + friend ATYPE get_values (const A&); + +protected: + N::ANON_E protected_; + static N::ANON_E s_protected_; + +private: + ATYPE private_; + static myenum s_private_; +}; + +const myenum A::s_public_ = E_A; +N::ANON_E A::s_protected_ = N::AA; +myenum A::s_private_ = E_C; + +static A::ATYPE +get_values (const A& a) +{ + A::ATYPE val; + + val = a.public_ + a.private_; // 1 + 3 + if (a.protected_ == N::AB) // + 21 + val += 21; + if (a.s_public_ == E_A) // +10 + val += 10; + if (a.s_protected_ == N::AA) // +20 + val += 20; + if (a.s_private_ == E_C) // +30 + val += 30; + return val; // = 85 +} + +typedef int A::*PMI; + +int +main (void) +{ + A a; + int var = 1234; + PMI pmi = &A::public_; + + return a.*pmi + get_values (a); // break here +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-member.exp b/gdb/testsuite/gdb.compile/cp-simple-member.exp new file mode 100644 index 00000000000..c9320d7c2f2 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-member.exp @@ -0,0 +1,76 @@ +# Copyright 2015-2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple method tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "a.public_" 1 +CompileExpression::test "a.protected_" {(21|N::AB)} +CompileExpression::test "a.private_" 3 +CompileExpression::test "A::s_public_" {(10|E_A)} +CompileExpression::test "A::s_protected_" {(20|N::AA)} +CompileExpression::test "A::s_private_" {(12|E_C)} +CompileExpression::test "A::ATYPE i = 10; var = i;" 10 -explicit +CompileExpression::test "get_values (a)" 85 +CompileExpression::test "myenum me = E_B; var = me;" 11 -explicit +CompileExpression::test "A::s_protected_ = N::AB; var = A::s_protected_;" \ + 21 -explicit +CompileExpression::test "A::s_private_ = E_B; var = A::s_private_;" 11 -explicit +CompileExpression::test "N::ANON_E ae = N::AD; var = ae;" 23 -explicit +CompileExpression::test {a.*pmi} 1 +CompileExpression::test {a.public_ = 2; var = a.*pmi; a.public_ = 1} 2 -explicit + +# Test some compilation failures +set failed {\r\nCompilation failed\.} +# !!keiths: This should actually really work... +gdb_test "compile code a.s_public_ = E_B" \ + ".*assignment of read-only variable 'A::s_public_'$failed" + +gdb_test "compile code get_values ()" \ + ".*too few arguments to function.*$failed" + +gdb_test "compile code ATYPE i;" \ + ".*.ATYPE. was not declared in this scope$failed" + +# !!keiths; The "to ..." part depends on how we name anonymous types. +gdb_test "compile code N::ANON_E nse = E_A" \ + ".*cannot convert .myenum. to .N::anonymous enum.*$failed" diff --git a/gdb/testsuite/gdb.compile/cp-simple-method.cc b/gdb/testsuite/gdb.compile/cp-simple-method.cc new file mode 100644 index 00000000000..c3c99696df6 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-method.cc @@ -0,0 +1,91 @@ +/* Copyright 2015, 2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +class A; +static int get_value (const A* a); + +class A +{ +public: + typedef int ATYPE; + + A (void) : a_ (21) {} + ATYPE get_var (void) { return a_; } + ATYPE get_var (unsigned long a) { return 100; } + ATYPE get_var (ATYPE a) { return 101; } + ATYPE get_var (float a) { return 102; } + ATYPE get_var (void *a) { return 103;} + ATYPE get_var (A& lr) { return 104; } + ATYPE get_var (A const& lr) { return 105; } + + ATYPE get_var1 (int n) { return a_ << n; } + ATYPE get_var2 (int incr, unsigned n) { return (a_ + incr) << n; } + + static ATYPE get_1 (int a) { return a + 1; } + static ATYPE get_2 (int a, int b) { return a + b + 2; } + + friend ATYPE get_value (const A*); + +private: + ATYPE a_; +}; + +static A::ATYPE +get_value (A::ATYPE a) +{ + return a; +} + +static A::ATYPE +get_value (const A* a) +{ + return a->a_; +} + +static A::ATYPE +get_value (void) +{ + return 200; +} + +typedef int (A::*PMF) (A::ATYPE); + +int +main (void) +{ + A *a = new A (); + int var = 1234; + float f = 1.23; + unsigned long ul = 0xdeadbeef; + A const* ac = a; + + PMF pmf = &A::get_var; + PMF *pmf_p = &pmf; + + var -= a->get_var (); // break here + var -= a->get_var (1); + var -= a->get_var (ul); + var -= a->get_var (f); + var -= a->get_var (a); + var -= a->get_var (*a); + var -= a->get_var (*ac); + var -= a->get_var1 (1); + var -= a->get_var2 (1, 2); + var += (a->*pmf) (1); + var -= (a->**pmf_p) (1); + + return var - A::get_1 (1) + A::get_2 (1, 2) + get_value () + + get_value (get_value ()) + get_value (a); +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-method.exp b/gdb/testsuite/gdb.compile/cp-simple-method.exp new file mode 100644 index 00000000000..ebb1273b6ce --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-method.exp @@ -0,0 +1,66 @@ +# Copyright 2015-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple method tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "a->get_var ()" 21 +CompileExpression::test "a->get_var (static_cast<unsigned long> (1))" 100 +CompileExpression::test "a->get_var (static_cast<int> (1))" 101 +CompileExpression::test "a->get_var (static_cast<float> (1))" 102 +CompileExpression::test "a->get_var (static_cast<void *> (a))" 103 +CompileExpression::test "a->get_var (*a)" 104 +CompileExpression::test "a->get_var (*ac)" 105 +CompileExpression::test "a->get_var1 (1)" 42 +CompileExpression::test "a->get_var2 (1, 2)" 88 +CompileExpression::test "A::get_1 (1)" 2 +CompileExpression::test "A::get_2 (1, 2)" 5 +CompileExpression::test "A::get_1 (a->get_var ())" 22 +CompileExpression::test "a->get_var1 (a->get_var () - 16)" 672 +CompileExpression::test "a->get_var2 (a->get_var (), A::get_1 (2))" 336 +CompileExpression::test "get_value ()" 200 +CompileExpression::test "get_value (a)" 21 +CompileExpression::test "get_value (get_value ())" 200 +CompileExpression::test {(a->*pmf) (1)} 101 +CompileExpression::test \ + {pmf = &A::get_var1; var = (a->*pmf) (2); pmf = &A::get_var} 84 -explicit +CompileExpression::test {(a->**pmf_p) (1)} 101 diff --git a/gdb/testsuite/gdb.compile/cp-simple-nested.cc b/gdb/testsuite/gdb.compile/cp-simple-nested.cc new file mode 100644 index 00000000000..50db34f1494 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-nested.cc @@ -0,0 +1,58 @@ +/* Copyright 2015-2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +class A +{ +public: + A (void) : a_ (1) {} + int get (void); + +protected: + int a_; + +private: + /* It is important to not /not/ use the nested class definition in A. + This exercises a different path through the code. */ + struct Inner1 + { + int a_; + Inner1 (void) : a_ (2) {} + + struct Inner2 + { + int a_; + Inner2 (void) : a_ (3) {} + }; + }; +}; + +int +A::get (void) +{ + A::Inner1 i1; + A::Inner1::Inner2 i2; + + return i1.a_ + i2.a_; // break here +} + +int var = 1234; + +int +main (void) +{ + A a; + + return a.get (); +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-nested.exp b/gdb/testsuite/gdb.compile/cp-simple-nested.exp new file mode 100644 index 00000000000..be3619740f4 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-nested.exp @@ -0,0 +1,52 @@ +# Copyright 2015-2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple virtual method/inheritance tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "i1.a_" 2 +CompileExpression::test "i2.a_" 3 +CompileExpression::test "A::Inner1 *i1p = &i1; var = i1p->a_;" 2 -explicit +CompileExpression::test "A::Inner1::Inner2 *i2p = &i2; var = i2p->a_;" 3 \ + -explicit +CompileExpression::test "A::Inner1 &r1 = i1; var = r1.a_;" 2 -explicit +CompileExpression::test "A::Inner1::Inner2 &r2 = i2; var = r2.a_;" 3 -explicit diff --git a/gdb/testsuite/gdb.compile/cp-simple-ns.cc b/gdb/testsuite/gdb.compile/cp-simple-ns.cc new file mode 100644 index 00000000000..56923edba14 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-ns.cc @@ -0,0 +1,37 @@ +namespace N1 +{ + namespace N2 + { + namespace N3 + { + namespace N4 + { + static int n4static = 400; + + struct S4 + { + static int s4static; + int s4int_; + S4 (void) : s4int_ (4) {}; + ~S4 (void) { --s4static; } + + int get_var (void) { return s4int_; } + static int get_svar (void) { return s4static; } + }; + int S4::s4static = 40; + } + } + } +} + +int +main (void) +{ + using namespace N1::N2::N3::N4; + + S4 s; + int var = 1234; + + var += s.s4int_; /* break here */ + return S4::get_svar () - 10 * s.get_var (); +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-ns.exp b/gdb/testsuite/gdb.compile/cp-simple-ns.exp new file mode 100644 index 00000000000..5d51a3d3d61 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-ns.exp @@ -0,0 +1,48 @@ +# Copyright 2015, 2016, 2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "N1::N2::N3::N4::n4static" 400 +CompileExpression::test "N1::N2::N3::N4::S4::s4static" 40 +CompileExpression::test "s.s4int_" 4 +CompileExpression::test "N1::N2::N3::N4::S4::get_svar ()" 40 +CompileExpression::test "s.get_var ()" 4 diff --git a/gdb/testsuite/gdb.compile/cp-simple-template.cc b/gdb/testsuite/gdb.compile/cp-simple-template.cc new file mode 100644 index 00000000000..ec46694757b --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-template.cc @@ -0,0 +1,180 @@ +/* Copyright 2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +// NOTE: We cannot currently use namespaces until namespace-qualified +// symbol lookups are fixed in gdb + +template <typename T, int V> +T mytemplate (int a) +{ + return static_cast<T> (a) + V; +} + +template <typename T, int V> +T mytemplate (void) +{ + return -V; +} + +template <int V = 100> +int mytemplate (void) +{ + return V; +} + +struct A +{ + A (int val) : value (val) { } + operator int () const { return value; } + + template <typename T = A> + T tempmethod (void) + { + return value; + } + + template <typename T = A, int V = -1> + static T stempmethod (void) + { + return V; + } + + template <typename T = A, int V = -2> + static T stempmethod (T arg) + { + return arg + V; + } + + int value; +}; + +template<> +int +A::tempmethod (void) +{ + return -value; +} + +template <typename T> +T deduct (T a) +{ + return a; +} + +extern char const g_str[] = "hello"; + +template <typename T> +int mod_test (T a) { return 1; } + +template <typename T> +int mod_test (T* const a) { return 2; } + +template <typename T> +int mod_test (T const* const a) { return 3; } + +#if 0 +/* This chaining of defaults has no good representation in the debug info. + For each instance where T2 defaulted to T1, we will have as many + default values in the debug info for T2, one for each such instance. */ +template <typename T1 = int, typename T2 = T1, typename T3 = T2, + int V1 = 10, int V2 = 20, const char* V3 = g_str> +T1 defaultvals (void) +{ + return static_cast<T1> (V1); +} +#else +template <typename T = A, int V = 10, const char* S = g_str> +T defaultvals (void) +{ + return static_cast<T> (V); +} +#endif + +// A handful of operator templates +struct O +{ + O (int v) : v_ (v) { } + + template <typename T> + operator T (void) { return -v_; } + + template <typename T> + O operator+ (T val) + { + return v_ + val; + } + + int v_; +}; + +template <typename T> +const T** ret_test (void) { return 0; } + +template <typename T> +T const* const* ret2_test (void) { return 0; } + +// Some simple class templates +template <typename T1 = O, typename T2 = int, int V = 3> +class classt +{ +public: + classt (T1 v) : val1_ (v), val2_ (107) { } + T1 get1 (void) const { return val1_; } + T2 get2 (void) const { return val2_; } + int get3 (void) const { return V; } + +private: + T1 val1_; + T2 val2_; +}; + +int +main (void) +{ + A a (20); + O o (30); + int var = 0xdeadbeef; + int i = 1; + const int j = 1; + int* pi = &i; + int const* const cpci = &j; + int *const cpi = &i; + + int o_val = o + 30; + int mod_value = mod_test (i) + mod_test (cpci) + mod_test (cpi); + const char** cp = ret_test<char> (); + char const* const* ccp = ret2_test<char> (); + + classt<> cddd (o); + classt<int> cdd (100); + classt<int, char> cd (101); + classt<int, char, 12> c (102); + int cvals = cddd.get1 () + cddd.get2 () + cddd.get3 (); + cvals += cdd.get1 () + cdd.get2 () + cdd.get3 (); + cvals += cd.get1 () + cd.get2 () + cd.get3 (); + cvals += c.get1 () + c.get2 () + c.get3 (); + + return mytemplate<int, 1> (0) + + mytemplate<int, 1> () + + mytemplate<0> () + + mytemplate () + + a.tempmethod () + + a.tempmethod<int> () + + A::stempmethod () + + A::stempmethod (0) + + defaultvals () + + defaultvals<int, 20> () + + deduct (0); // break here +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-template.exp b/gdb/testsuite/gdb.compile/cp-simple-template.exp new file mode 100644 index 00000000000..7261eed332a --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-template.exp @@ -0,0 +1,79 @@ +# Copyright 2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple template tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "mytemplate<int, 1> ()" -1 +CompileExpression::test "mytemplate<int, 1> (1)" 2 +CompileExpression::test "mytemplate<0> ()" 0 +CompileExpression::test "mytemplate ()" 100 +CompileExpression::test "a.tempmethod ()" {(20|{value = 20})} \ + -print {xfail *-*-* gcc/debug/49348} \ + -value {xfail *-*-* gcc/debug/49348} +CompileExpression::test "a.tempmethod<A> ()" {(20|{value = 20})} +CompileExpression::test "a.tempmethod<int> ()" -20 +CompileExpression::test "defaultvals ()" {(10|{value = 10})} +CompileExpression::test "defaultvals<int, 20> ()" 20 +CompileExpression::test "deduct (1234)" 1234 +CompileExpression::test "o + 3" {(-33|{v_ = 33})} +CompileExpression::test "mod_test (i)" 1 +CompileExpression::test "mod_test (cpi)" 2 +CompileExpression::test "mod_test (cpci)" 3 +CompileExpression::test "cddd.get1 ()" {(-30|{v_ = 30})} +CompileExpression::test "cddd.get2 ()" 107 +CompileExpression::test "cddd.get3 ()" 3 +CompileExpression::test "cdd.get1 ()" 100 +CompileExpression::test "cdd.get2 ()" 107 +CompileExpression::test "cdd.get3 ()" 3 +CompileExpression::test "cd.get1 ()" 101 +CompileExpression::test "cd.get2 ()" {107( 'k')?} +CompileExpression::test "cd.get3 ()" 3 +CompileExpression::test "c.get1 ()" 102 +CompileExpression::test "c.get2 ()" {107( 'k')?} +CompileExpression::test "c.get3 ()" 12 + +# Some explicit tests that don't fit neatly into CompileExpression (yet) +gdb_test "compile print ret_test<char>()" \ + [string_to_regexp {= (const char **) 0x0}] +gdb_test "compile print ret2_test<char>()" \ + [string_to_regexp {= (const char * const *) 0x0}] diff --git a/gdb/testsuite/gdb.compile/cp-simple-virtual.cc b/gdb/testsuite/gdb.compile/cp-simple-virtual.cc new file mode 100644 index 00000000000..f778d70a9b3 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-virtual.cc @@ -0,0 +1,65 @@ +/* Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +struct A +{ + virtual int doit (void) { return 1; } + virtual int doit3 (void) { return -3; } + virtual int doit2 (void) = 0; +}; + +struct B : virtual A +{ + int doit (void) { return 2; } + int doit2 (void) { return 22; } +}; + +struct C : virtual A +{ + int doit (void) { return 3; } + int doit2 (void) { return 33; } +}; + +struct D : B, C +{ + int doit (void) { return 4; } + int doit2 (void) { return 44; } +}; + +int +main (void) +{ + int var = 1234; + B b; + C c; + D d; + A *ap = &d; + + struct Foo + { + int doit (void) { return 1111; } + } foo; + + struct Bar : A + { + int doit2 (void) { return 2222; } + } bar; + + var = (b.doit () + c.doit () + d.doit () + d.doit3 () + + ap->doit () + ap->doit2 () + foo.doit () + + bar.doit2 ()); // break here + + return 0; +} diff --git a/gdb/testsuite/gdb.compile/cp-simple-virtual.exp b/gdb/testsuite/gdb.compile/cp-simple-virtual.exp new file mode 100644 index 00000000000..44bb3dd7250 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-simple-virtual.exp @@ -0,0 +1,72 @@ +# Copyright 2015, 2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple virtual method/inheritance tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +CompileExpression::new "var" +CompileExpression::test "b.doit ()" 2 +CompileExpression::test "c.doit ()" 3 +CompileExpression::test "d.doit ()" 4 +CompileExpression::test "ap->doit ()" 4 +CompileExpression::test "b.doit2 ()" 22 +CompileExpression::test "c.doit2 ()" 33 +CompileExpression::test "d.doit2 ()" 44 +CompileExpression::test "ap->doit2 ()" 44 +CompileExpression::test "b.doit3 ()" -3 +CompileExpression::test "c.doit3 ()" -3 +CompileExpression::test "d.doit3 ()" -3 +CompileExpression::test "foo.doit ()" 1111 +CompileExpression::test "bar.doit2 ()" 2222 + +# These two tests are "disabled". They represent new/future features. +# CompileExpression::test \ + [concat "struct ABC {int doit2(void) { return 3333; }} abc;" \ + "var = abc.doit2()"] \ + 3333 -explicit +# CompileExpression::test \ + [concat "struct ABC : A {int doit2(void) { return 4444; }} abc;" \ + "var = abc.doit2()"] \ + 4444 -explicit + +# Test some error conditions +gdb_test "compile code A a;" \ + ".*cannot declare variable .a. to be of abstract type.*Compilation failed." diff --git a/gdb/testsuite/gdb.compile/cp-special-function.cc b/gdb/testsuite/gdb.compile/cp-special-function.cc new file mode 100644 index 00000000000..6bb5ea596c5 --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-special-function.cc @@ -0,0 +1,661 @@ +/* Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <cstddef> + +class MyInteger; +static MyInteger *global_integer; + +class MyInteger +{ +public: + MyInteger (int val) : pub_var (0), int_ (val) {} + int get (void) const { return int_; } + + /* Don't assume that these operators do exactly what you + think they will -- especially the unary versions of +,-,*,&. */ + + friend MyInteger operator+ (const MyInteger& i); + friend int operator+ (const MyInteger& i1, const MyInteger& i2); + friend int operator+ (const MyInteger& i1, int i2); + friend int operator+ (int i1, const MyInteger& i2); + + friend MyInteger operator- (const MyInteger& i); + friend int operator- (const MyInteger& i1, const MyInteger& i2); + friend int operator- (const MyInteger& i1, int i2); + friend int operator- (int i1, const MyInteger& i2); + + friend MyInteger operator& (const MyInteger& i); + friend int operator& (const MyInteger& i1, const MyInteger& i2); + friend int operator& (const MyInteger& i1, int i2); + friend int operator& (int i1, const MyInteger& i2); + + friend MyInteger operator* (const MyInteger& i); + friend int operator* (const MyInteger& i1, const MyInteger& i2); + friend int operator* (const MyInteger& i1, int i2); + friend int operator* (int i1, const MyInteger& i2); + + friend MyInteger operator~ (const MyInteger& i); + + friend int operator/ (const MyInteger& i1, const MyInteger& i2); + friend int operator/ (const MyInteger& i1, int i2); + friend int operator/ (int i1, const MyInteger& i2); + + friend int operator% (const MyInteger& i1, const MyInteger& i2); + friend int operator% (const MyInteger& i1, int i2); + friend int operator% (int i1, const MyInteger& i2); + + friend int operator| (const MyInteger& i1, const MyInteger& i2); + friend int operator| (const MyInteger& i1, int i2); + friend int operator| (int i1, const MyInteger& i2); + + friend int operator^ (const MyInteger& i1, const MyInteger& i2); + friend int operator^ (const MyInteger& i1, int i2); + friend int operator^ (int i1, const MyInteger& i2); + + void operator= (const MyInteger& i) { int_ = i.int_; } + void operator= (int i) { int_ = i; } + + void operator+= (const MyInteger& i) { int_ += i.int_; } + void operator+= (int i) { int_ += i; } + + void operator-= (const MyInteger& i) { int_ -= i.int_; } + void operator-= (int i) { int_ -= i; } + + void operator*= (const MyInteger& i) { int_ *= i.int_; } + void operator*= (int i) { int_ *= i; } + + void operator/= (const MyInteger& i) { int_ /= i.int_; } + void operator/= (int i) { int_ /= i; } + + void operator%= (const MyInteger& i) { int_ %= i.int_; } + void operator%= (int i) { int_ %= i; } + + void operator&= (const MyInteger& i) { int_ &= i.int_; } + void operator&= (int i) { int_ &= i; } + + void operator|= (const MyInteger& i) { int_ |= i.int_; } + void operator|= (int i) { int_ |= i; } + + void operator^= (const MyInteger& i) { int_ ^= i.int_; } + void operator^= (int i) { int_ ^= i; } + + friend int operator<< (const MyInteger& i1, const MyInteger& i2); + friend int operator<< (const MyInteger& i1, int i2); + friend int operator<< (int i1, const MyInteger& i2); + + friend int operator>> (const MyInteger& i1, const MyInteger& i2); + friend int operator>> (const MyInteger& i1, int i2); + friend int operator>> (int i1, const MyInteger& i2); + + void operator<<= (const MyInteger& i) { int_ <<= i.int_; } + void operator<<= (int i) { int_ <<= i; } + + void operator>>= (const MyInteger& i) { int_ >>= i.int_; } + void operator>>= (int i) { int_ >>= i; } + + friend bool operator== (const MyInteger& i1, const MyInteger& i2); + friend bool operator== (const MyInteger& i1, int i2); + friend bool operator== (int i1, const MyInteger& i2); + + friend bool operator!= (const MyInteger& i1, const MyInteger& i2); + friend bool operator!= (const MyInteger& i1, int i2); + friend bool operator!= (int i1, const MyInteger& i2); + + friend bool operator< (const MyInteger& i1, const MyInteger& i2); + friend bool operator< (const MyInteger& i1, int i2); + friend bool operator< (int i1, const MyInteger& i2); + + friend bool operator> (const MyInteger& i1, const MyInteger& i2); + friend bool operator> (const MyInteger& i1, int i2); + friend bool operator> (int i1, const MyInteger& i2); + + friend bool operator<= (const MyInteger& i1, const MyInteger& i2); + friend bool operator<= (const MyInteger& i1, int i2); + friend bool operator<= (int i1, const MyInteger& i2); + + friend bool operator>= (const MyInteger& i1, const MyInteger& i2); + friend bool operator>= (const MyInteger& i1, int i2); + friend bool operator>= (int i1, const MyInteger& i2); + + friend int operator! (const MyInteger& i); + + friend bool operator&& (const MyInteger& i1, const MyInteger& i2); + friend bool operator&& (const MyInteger& i1, int i2); + friend bool operator&& (int i1, const MyInteger& i2); + + friend bool operator|| (const MyInteger& i1, const MyInteger& i2); + friend bool operator|| (const MyInteger& i1, int i2); + friend bool operator|| (int i1, const MyInteger& i2); + + MyInteger& operator++ (void) { ++int_; return *this; } + MyInteger operator++ (int dummy) + { + MyInteger tmp (int_); + operator++ (); + return tmp; + } + + MyInteger& operator-- (void) { --int_; return *this; } + MyInteger operator-- (int dummy) + { + MyInteger tmp (int_); + operator-- (); + return tmp; + } + + friend MyInteger& operator, (MyInteger& i1, MyInteger& i2); + + friend int operator->* (const MyInteger& i1, int i2); + friend int operator->* (const MyInteger& i1, const MyInteger& i2); + + MyInteger* operator-> (void) { return global_integer; } + + int operator() (void) { return -int_; } + int operator() (const MyInteger& i) { return int_ + i; } + int operator() (int i) { return int_ + i; } + + int operator[] (const MyInteger& i) { return int_ - i; } + int operator[] (int i) { return int_ - i; } + +#if 1 + static void* operator new (std::size_t sz); +#endif + + operator int() const { return -int_; } + operator char() const { return int_ & 0xff; } + +public: + int pub_var; +private: + int int_; +}; + +MyInteger +operator+ (const MyInteger& i) +{ + return MyInteger (i + 10); +} + +int +operator+ (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ + i2.int_; +} + +int +operator+ (const MyInteger& i1, int i2) +{ + return i1.int_ + i2; +} + +int +operator+ (int i1, const MyInteger& i2) +{ + return operator+ (i2, i1); +} + +MyInteger +operator- (const MyInteger& i) +{ + return MyInteger (i + 20); +} + +int +operator- (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ - i2.int_; +} + +int +operator- (const MyInteger& i1, int i2) +{ + return i1.int_ - i2; +} + +int +operator- (int i1, const MyInteger& i2) +{ + return i1 - i2.int_; +} + +MyInteger +operator& (const MyInteger& i) +{ + return MyInteger (i + 30); +} + +int +operator& (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ & i2.int_; +} + +int +operator& (const MyInteger& i1, int i2) +{ + return i1.int_ & i2; +} + +int +operator& (int i1, const MyInteger& i2) +{ + return operator& (i2, i1); +} + +MyInteger +operator* (const MyInteger& i) +{ + return MyInteger (i + 40); +} + +int +operator* (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ * i2.int_; +} + +int +operator* (const MyInteger& i1, int i2) +{ + return i1.int_ * i2; +} + +int +operator* (int i1, const MyInteger& i2) +{ + return operator* (i2, i1); +} + +MyInteger +operator~ (const MyInteger& i) +{ + return MyInteger (~i.int_); +} + +int +operator/ (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ / i2.int_; +} + +int +operator/ (const MyInteger& i1, int i2) +{ + return i1.int_ / i2; +} + +int +operator/ (int i1, const MyInteger& i2) +{ + return i1 / i2.int_; +} + +int +operator% (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ % i2.int_; +} + +int +operator% (const MyInteger& i1, int i2) +{ + return i1.int_ % i2; +} + +int +operator% (int i1, const MyInteger& i2) +{ + return i1 % i2.int_; +} + +int +operator| (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ | i2.int_; +} + +int +operator| (const MyInteger& i1, int i2) +{ + return i1.int_ | i2; +} + +int +operator| (int i1, const MyInteger& i2) +{ + return i1 | i2.int_; +} + +int +operator^ (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ ^ i2.int_; +} + +int +operator^ (const MyInteger& i1, int i2) +{ + return i1.int_ ^ i2; +} + +int +operator^ (int i1, const MyInteger& i2) +{ + return i1 ^ i2.int_; +} + +int +operator<< (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ << i2.int_; +} + +int +operator<< (const MyInteger& i1, int i2) +{ + return i1.int_ << i2; +} + +int +operator<< (int i1, const MyInteger& i2) +{ + return i1 << i2.int_; +} + +int +operator>> (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ >> i2.int_; +} + +int +operator>> (const MyInteger& i1, int i2) +{ + return i1.int_ >> i2; +} + +int +operator>> (int i1, const MyInteger& i2) +{ + return i1 >> i2.int_; +} + +bool +operator== (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ == i2.int_; +} + +bool +operator== (const MyInteger& i1, int i2) +{ + return i1.int_ == i2; +} + +bool +operator== (int i1, const MyInteger& i2) +{ + return operator== (i2, i1); +} + +bool +operator!= (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ != i2.int_; +} + +bool +operator!= (const MyInteger& i1, int i2) +{ + return i1.int_ != i2; +} + +bool +operator!= (int i1, const MyInteger& i2) +{ + return operator!= (i2, i1); +} + +bool +operator< (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ < i2.int_; +} + +bool +operator< (const MyInteger& i1, int i2) +{ + return i1.int_ < i2; +} + +bool +operator< (int i1, const MyInteger& i2) +{ + return i1 < i2.int_; +} + +bool +operator> (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ > i2.int_; +} + +bool +operator> (const MyInteger& i1, int i2) +{ + return i1.int_ > i2; +} + +bool +operator> (int i1, const MyInteger& i2) +{ + return i1 > i2.int_; +} + +bool +operator<= (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ <= i2.int_; +} + +bool +operator<= (const MyInteger& i1, int i2) +{ + return i1.int_ <= i2; +} + +bool +operator<= (int i1, const MyInteger& i2) +{ + return i1 <= i2.int_; +} + +bool +operator>= (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ >= i2.int_; +} + +bool +operator>= (const MyInteger& i1, int i2) +{ + return i1.int_ >= i2; +} + +bool +operator>= (int i1, const MyInteger& i2) +{ + return i1 >= i2.int_; +} + +int +operator! (const MyInteger& i) +{ + return !(i.int_); +} + +bool +operator&& (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ && i2.int_; +} + +bool +operator&& (const MyInteger& i1, int i2) +{ + return i1.int_ && i2; +} + +bool +operator&& (int i1, const MyInteger& i2) +{ + return operator&& (i2, i1); +} + +bool +operator|| (const MyInteger& i1, const MyInteger& i2) +{ + return i1.int_ || i2.int_; +} + +bool +operator|| (const MyInteger& i1, int i2) +{ + return i1.int_ || i2; +} + +bool +operator|| (int i1, const MyInteger& i2) +{ + return operator|| (i2, i1); +} + +MyInteger& +operator, (MyInteger& i1, MyInteger& i2) +{ + return i1; +} + +int +operator->* (const MyInteger& i1, int i2) +{ + return i1 + i2; +} + +int +operator->* (const MyInteger& i1, const MyInteger& i2) +{ + return i1 + i2; +} + +int +operator"" _MI (unsigned long long i) +{ + return 100; +} + +int +operator"" _MI (char c) +{ + return 200; +} + +int +operator"" _MI (const char *str, std::size_t len) +{ + return 300; +} + +#if 1 +static void* +MyInteger::operator new (std::size_t sz) +{ + void* p = ::operator new (sz); + MyInteger* obj = static_cast<MyInteger*> (p); + + obj->pub_var = 1234; + return p; +} +#endif + +int +main (void) +{ + char ch; + int var; + MyInteger a (1), b (2), c (-3), d (0); + + global_integer = new MyInteger (21); + global_integer->pub_var = -21; + ch = *global_integer; + d = a; + d = 0; + d += a; + d += 1; + d -= a; + d -= 1; + d *= 1; + d *= d; + d = 2; + d /= 1; + d /= d; + d %= 2; + d %= a; + d = 2; + d &= 1; + d &= a; + d |= 2; + d |= a; + d ^= 1; + d ^= b; + d <<= 2; + d <<= a; + d >>= 2; + d >>= a; + d++; + ++d; + d--; + --d; + d = 1234; + var = d; + return +c + a + b + 3 + a.get () + - a - 2 - a - b + (-c) + + a & b + a & 1 + * a * b * 2 * c + + ~c + + a / 1 + b / a + 1 / a + + a % b + a % 1 + 2 % b + + 1|b + a|2 + a|b + + 1^a + b^2 + a^b + + 1 << a + a << 1 + a << a + + 10 >> a + b >> 1 + b >> a + + a == 1 + a == b + 1 == a + + a != 1 + a != b + 1 != a + + (a < 1) + (a < b) + (2 < a) + + (a > 1) + (a > b) + (2 > a) + + (a <= 1) + (a <= b) + (2 <= a) + + (a >= 1) + (a >= b) + (2 >= a) + + (!a) + + (a && 0) + (a && b) + (1 && a) + + (a || 0) + (a || b) + (1 || a) + + (a,b) + + a->*1 + a->*b + + a->pub_var + + a () + a (a) + a (2) + + a [1] + b [a] + + 'a'_MI + 1234_MI + "hello"_MI + ; // break here +} diff --git a/gdb/testsuite/gdb.compile/cp-special-function.exp b/gdb/testsuite/gdb.compile/cp-special-function.exp new file mode 100644 index 00000000000..fcbbfcea65e --- /dev/null +++ b/gdb/testsuite/gdb.compile/cp-special-function.exp @@ -0,0 +1,260 @@ +# Copyright 2015, 2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# (Very) simple method tests. + +load_lib compile-support.exp + +standard_testfile .cc + +if {[skip_cplus_tests]} { + untested "skipping C++ tests" + return +} + +if {[prepare_for_testing $testfile $testfile $srcfile \ + {debug nowarnings c++ additional_flags=-std=c++11}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested \ + "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break here" $srcfile] +gdb_continue_to_breakpoint "testing location" + +# Reminder, "var" is an integer; all these types get converted to `int'. +CompileExpression::new "var" +CompileExpression::test "a + 1" 2 +CompileExpression::test "a + b" 3 +CompileExpression::test "a + b + 3" 6 +CompileExpression::test "1 + a + a" 3 +CompileExpression::test "1 + b + 1" 4 +CompileExpression::test "(+a).get ()" 11 +CompileExpression::test "(+c).get ()" 7 +CompileExpression::test "a + (+c).get ()" 8 + +CompileExpression::test "a - 2" -1 +CompileExpression::test "a - b" -1 +CompileExpression::test "a - b - 3" -4 +CompileExpression::test "2 - a - a" 0 +CompileExpression::test "2 - b - 2" -2 +CompileExpression::test "(-a).get ()" 21 +CompileExpression::test "(-c).get ()" 17 +CompileExpression::test "a - (-c).get ()" -16 + +CompileExpression::test "a & 3" 1 +CompileExpression::test "a & b" 0 +CompileExpression::test "a & b & 3" 0 +CompileExpression::test "3 & a & a" 1 +CompileExpression::test "3 & b & 3" 2 +CompileExpression::test "(&a).get ()" 31 +CompileExpression::test "(&c).get ()" 27 +CompileExpression::test "a & (&c).get ()" 1 + +CompileExpression::test "a * 4" 4 +CompileExpression::test "a * b" 2 +CompileExpression::test "a * b * 4" 8 +CompileExpression::test "4 * a * a" 4 +CompileExpression::test "4 * b * 4" 32 +CompileExpression::test "(*a).get ()" 41 +CompileExpression::test "(*c).get ()" 37 +CompileExpression::test "a * (*c).get ()" 37 + +CompileExpression::test "(~a).get ()" -2 +CompileExpression::test "(~b).get ()" -3 +CompileExpression::test "(~c).get ()" 2 + +CompileExpression::test "a / 1" 1 +CompileExpression::test "10 / b" 5 +CompileExpression::test "b / a" 2 +CompileExpression::test "-3 / c / 1 / a" 1 + +CompileExpression::test "a % 1" 0 +CompileExpression::test "5 % c" 2 +CompileExpression::test "a % c" 1 +CompileExpression::test "-2 % c % b % 1" 0 + +CompileExpression::test "a | 1" 1 +CompileExpression::test "1 | b" 3 +CompileExpression::test "b | c" -1 +CompileExpression::test "1 | a | b | 4" 7 + +CompileExpression::test "a ^ 1" 0 +CompileExpression::test "1 ^ b" 3 +CompileExpression::test "b ^ c" -1 +CompileExpression::test "1 ^ a ^ b ^ 4" 6 + +# !!keiths: I don't know why this is failing... +CompileExpression::test "d = b; var = d.get ();" 2 -explicit +CompileExpression::test "d = 21; var = d.get ();" 21 -explicit +CompileExpression::test "d = 0; var = d.get ();" 0 -explicit + +CompileExpression::test "d.int_ = 1; var = d.get ()" 1 -explicit +CompileExpression::test "d += a; var = d.get ();" 2 -explicit +CompileExpression::test "d += 2; var = d.get ();" 4 -explicit + +CompileExpression::test "d.int_ = 2; var = d.get ()" 2 -explicit +CompileExpression::test "d -= a; var = d.get ();" 1 -explicit +CompileExpression::test "d -= 2; var = d.get ();" -1 -explicit + +CompileExpression::test "d.int_ = 3; var = d.get ()" 3 -explicit +CompileExpression::test "d *= 2; var = d.get ()" 6 -explicit +CompileExpression::test "d *= d; var = d.get ()" 36 -explicit + +CompileExpression::test "d.int_ = 6; var = d.get ()" 6 -explicit +CompileExpression::test "d /= 2; var = d.get ()" 3 -explicit +CompileExpression::test "d /= d; var = d.get ()" 1 -explicit + +CompileExpression::test "d.int_ = 4; var = d.get ()" 4 -explicit +CompileExpression::test "d %= 3; var = d.get ()" 1 -explicit +CompileExpression::test "d %= d; var = d.get ()" 0 -explicit + +CompileExpression::test "d.int_ = 5; var = d.get ()" 5 -explicit +CompileExpression::test "d &= 4; var = d.get ()" 4 -explicit +CompileExpression::test "d &= a; var = d.get ()" 0 -explicit + +CompileExpression::test "d.int_ = 8; var = d.get ()" 8 -explicit +CompileExpression::test "d |= a; var = d.get ()" 9 -explicit +CompileExpression::test "d |= 16; var = d.get ()" 25 -explicit + +CompileExpression::test "d.int_ = 9; var = d.get ()" 9 -explicit +CompileExpression::test "d ^= 2; var = d.get ()" 11 -explicit +CompileExpression::test "d ^= d; var = d.get ()" 0 -explicit + +CompileExpression::test "d.int_ = 10; var = d.get ()" 10 -explicit +CompileExpression::test "d << 2" 40 +CompileExpression::test "d << a" 20 +CompileExpression::test "1 << b" 4 + +CompileExpression::test "d.int_ = 12; var = d.get ()" 12 -explicit +CompileExpression::test "d >> 2" 3 +CompileExpression::test "d >> a" 6 +CompileExpression::test "10 >> a" 5 + +CompileExpression::test "d.int_ = 13; var = d.get ()" 13 -explicit +CompileExpression::test "d <<= 2; var = d.get ()" 52 -explicit +CompileExpression::test "d <<= a; var = d.get ()" 104 -explicit + +CompileExpression::test "d.int_ = 14; var = d.get ()" 14 -explicit +CompileExpression::test "d >>= 2; var = d.get ()" 3 -explicit +CompileExpression::test "d >>= a; var = d.get ()" 1 -explicit + +CompileExpression::test "d.int_ = 1013; var = d.get ()" 1013 -explicit +CompileExpression::test "d == 2" {(0|false)} +CompileExpression::test "d == d" {(1|true)} +CompileExpression::test "1 == d" {(0|false)} + +CompileExpression::test "d.int_ = 1014; var = d.get ()" 1014 -explicit +CompileExpression::test "d != 2" {(1|true)} +CompileExpression::test "d != d" {(0|false)} +CompileExpression::test "1014 == d" {(1|true)} + +CompileExpression::test "d.int_ = 15; var = d.get ()" 15 -explicit +CompileExpression::test "d < 2" {(0|false)} +CompileExpression::test "a < d" {(1|true)} +CompileExpression::test "16 < d" {(0|false)} + +CompileExpression::test "d.int_ = 16; var = d.get ()" 16 -explicit +CompileExpression::test "d > 2" {(1|true)} +CompileExpression::test "d < a" {(0|false)} +CompileExpression::test "15 < d" {(1|true)} + +CompileExpression::test "d.int_ = 17; var = d.get ()" 17 -explicit +CompileExpression::test "d <= 2" {(0|false)} +CompileExpression::test "a <= d" {(1|true)} +CompileExpression::test "18 <= d" {(0|false)} + +CompileExpression::test "d.int_ = 18; var = d.get ()" 18 -explicit +CompileExpression::test "d >= 2" {(1|true)} +CompileExpression::test "d <= a" {(0|false)} +CompileExpression::test "15 <= d" {(1|true)} + +CompileExpression::test "d.int_ = 19; var = d.get ()" 19 -explicit +CompileExpression::test "!d" {(0|false)} + +CompileExpression::test "d.int_ = 20; var = d.get ()" 20 -explicit +CompileExpression::test "d && 0" {(0|false)} +CompileExpression::test "d && a" {(1|true)} +CompileExpression::test "0 && d" {(0|false)} + +CompileExpression::test "d.int_ = 21; var = d.get ()" 21 -explicit +CompileExpression::test "d || 0" {(1|true)} +CompileExpression::test "d || a" {(1|true)} +CompileExpression::test "0 || d" {(1|true)} + +CompileExpression::test "d.int_ = 22; var = d.get ()" 22 -explicit +CompileExpression::test "(d++).get ()" 22 -noprint +CompileExpression::test "(d++).get ()" 23 -nocode +CompileExpression::test "d.get ()" 24 -name "get value of post-incr d" +CompileExpression::test "(++d).get ()" 25 -noprint +CompileExpression::test "(++d).get ()" 26 -nocode + +CompileExpression::test "d.int_ = 23; var = d.get ()" 23 -explicit +CompileExpression::test "(d--).get ()" 23 -noprint +CompileExpression::test "(d--).get ()" 22 -nocode +CompileExpression::test "d.get ()" 21 -name "get value of post-decr d" +CompileExpression::test "(--d).get ()" 20 -noprint +CompileExpression::test "(--d).get ()" 19 -nocode + +CompileExpression::test "d.int_ = 24; var = d.get ()" 24 -explicit +CompileExpression::test "(a,d).get ()" 1 +CompileExpression::test "(d,a).get ()" 24 + +CompileExpression::test "d.int_ = 25; var = d.get ()" 25 -explicit +CompileExpression::test "d->*3" 28 +CompileExpression::test "d->*b" 27 "d->*b 1" + +CompileExpression::test "d.int_ = 26; var = d.get ()" 26 -explicit +CompileExpression::test "d->*4" 30 +CompileExpression::test "d->*b" 28 "d->*b 2" + +CompileExpression::test "d.pub_var = 1; var = d.pub_var" 1 -explicit +CompileExpression::test "d->pub_var" -21 + +# "'d' cannot be used as function" + CompileExpression::test "d.int_ = 27; var = d.get ()" 27 -explicit + CompileExpression::test "d ()" -27 + CompileExpression::test "d (3)" 30 + CompileExpression::test "a (b)" 3 + +CompileExpression::test "d.int_ = 28; var = d.get ()" 28 -explicit +CompileExpression::test "d\[10\]" 18 +CompileExpression::test "d\[b\]" 26 + +# "unable to find XYZ literal operator 'operator""_MI'" + CompileExpression::test "10_MI" 100 + CompileExpression::test "'c'_MI" 200 + CompileExpression::test "\"foo\"_MI" 300 + +# crash + CompileExpression::test \ + "MyInteger *myint_ptr = new MyInteger (1); var = myint_ptr->pub_var" \ + 1234 -explicit + +CompileExpression::test "d.int_ = 29; var = d.int_" 29 -explicit +CompileExpression::test "ch = d; var = ch;" 29 -explicit +CompileExpression::test "char a_char = d; var = a_char - 9" 20 -explicit + +CompileExpression::test "d.int_ = 30; var = d.int_" 30 -explicit +CompileExpression::test "d" {(-30|{pub_var = 1, int_ = 30})} +CompileExpression::test "int integer = d; var = integer - 10" -40 -explicit |