For practitioners of other languages it is useful to indicate that an access value is not a legal operand of predefined concatenation.
Compiling foo.adb must yield: foo.adb:5:33: invalid operand types for operator "&" foo.adb:5:33: left operand is access type foo.adb:6:35: invalid operand types for operator "&" foo.adb:6:35: right operand is access type with Ada.Text_IO; use Ada.Text_IO; procedure Foo is Prefix : access String := new String'("Hello "); Suffix : String := Prefix & "world!"; Backwards : String := "world!" & Prefix; begin Put_Line (Suffix); end Foo; Tested on x86_64-pc-linux-gnu, committed on trunk 2014-01-22 Ed Schonberg <schonb...@adacore.com> * sem_ch4.adb (Operator_Check): Improve error message when an operand of concatenation is an access type.
Index: sem_ch4.adb =================================================================== --- sem_ch4.adb (revision 206918) +++ sem_ch4.adb (working copy) @@ -6151,7 +6151,8 @@ -- In an instance a generic actual may be a numeric type even if -- the formal in the generic unit was not. In that case, the -- predefined operator was not a possible interpretation in the - -- generic, and cannot be one in the instance. + -- generic, and cannot be one in the instance, unless the operator + -- is an actual of an instance. if In_Instance and then @@ -6576,6 +6577,17 @@ if Nkind (N) /= N_Op_Concat then Error_Msg_NE ("\left operand has}!", N, Etype (L)); Error_Msg_NE ("\right operand has}!", N, Etype (R)); + + -- For concatenation operators it is more difficult to + -- determine which is the wrong operand. It is worth + -- flagging explicitly an access type, for those who + -- might think that a dereference happens here. + + elsif Is_Access_Type (Etype (L)) then + Error_Msg_N ("\left operand is access type", N); + + elsif Is_Access_Type (Etype (R)) then + Error_Msg_N ("\right operand is access type", N); end if; end if; end if;