Browse Source

Fix for Mantis #17598. When extended syntax is off allow the result of constructors to be dropped when the constructor is called as an instance method instead of a class method.

pstatmnt.pas, statement:
  * check whether the constructor is called as an instance or class method
nflw.pas, tlabelnode.pass_1:
  * don't check the owner of the labelsym when there is none (happens with internally created labels like for e.g. exception handling)

+ added test  

git-svn-id: trunk@25068 -
svenbarth 12 years ago
parent
commit
407e9d173b
4 changed files with 41 additions and 2 deletions
  1. 1 0
      .gitattributes
  2. 2 0
      compiler/nflw.pas
  3. 8 2
      compiler/pstatmnt.pas
  4. 30 0
      tests/webtbs/tw17598.pp

+ 1 - 0
.gitattributes

@@ -13100,6 +13100,7 @@ tests/webtbs/tw17550.pp svneol=native#text/plain
 tests/webtbs/tw17560.pp svneol=native#text/plain
 tests/webtbs/tw1758.pp svneol=native#text/plain
 tests/webtbs/tw17591.pp svneol=native#text/plain
+tests/webtbs/tw17598.pp svneol=native#text/pascal
 tests/webtbs/tw17604.pp svneol=native#text/plain
 tests/webtbs/tw17646.pp svneol=native#text/plain
 tests/webtbs/tw1765.pp svneol=native#text/plain

+ 2 - 0
compiler/nflw.pas

@@ -1874,6 +1874,8 @@ implementation
         if assigned(left) then
           firstpass(left);
         if (m_non_local_goto in current_settings.modeswitches) and
+            { the owner can be Nil for internal labels }
+            assigned(labsym.owner) and
           (current_procinfo.procdef.parast.symtablelevel<>labsym.owner.symtablelevel) then
           CGMessage(cg_e_labels_cannot_defined_outside_declaration_scope)
       end;

+ 8 - 2
compiler/pstatmnt.pas

@@ -1295,8 +1295,14 @@ implementation
                     not(is_void(p.resultdef)) and
                     { can be nil in case there was an error in the expression }
                     assigned(tcallnode(p).procdefinition) and
-                    not((tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
-                        is_object(tprocdef(tcallnode(p).procdefinition).struct)) then
+                    { allow constructor calls to drop the result if they are
+                      called as instance methods instead of class methods }
+                    not(
+                      (tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
+                      is_class_or_object(tprocdef(tcallnode(p).procdefinition).struct) and
+                      assigned(tcallnode(p).methodpointer) and
+                      (tnode(tcallnode(p).methodpointer).resultdef.typ=objectdef)
+                    ) then
                    Message(parser_e_illegal_expression);
                end;
              code:=p;

+ 30 - 0
tests/webtbs/tw17598.pp

@@ -0,0 +1,30 @@
+{ %NORUN }
+
+{$mode macpas}
+{$extendedsyntax off}
+{$modeswitch exceptions+}
+{$modeswitch class+}
+
+program tw17598;
+
+  uses
+    sysutils;
+
+  type
+    EMyException =
+      class( Exception)
+        constructor Create( theMessage: Ansistring);
+      end;
+
+constructor EMyException.Create( theMessage: Ansistring);
+    begin
+      inherited Create( theMessage)
+    end;
+
+begin
+  try
+    raise EMyException.Create( 'my exception raised')
+  except
+    ShowException( ExceptObject, ExceptAddr)
+  end
+end.