basic/qa/basic_coverage/test_variant_arg_used_as_obj.bas |   38 +++++++++++++++
 basic/source/comp/exprtree.cxx                           |    7 +-
 2 files changed, 43 insertions(+), 2 deletions(-)

New commits:
commit ba0a55592a93de3f22888dc49b74509fd1d8f08c
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Jan 23 22:07:29 2025 +0500
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Jan 23 22:35:53 2025 +0100

    tdf#160578: do not modify procedure argument type based on its use
    
    Since the initial import, there is a code in SbiExpression::Term, that
    checks if the defined symbol is used as object (e.g., dot notation to
    access its members), and then, if its defined type is Variant, then it
    is corrected to Object. There is no rationale for this in comments; so
    I have no way to know what could break if that core is dropped.
    
    It's obvious that at least for procedure arguments, such correction is
    wrong: the argument definition is the procedure's API; and the actual
    use of the symbol should not unexpectedly change what is advertised.
    
    This change limits the application of the correction to non-arguments.
    If it should be dropped completely is a separate question.
    
    Change-Id: Ia902afa3f744d0d51510ba6903be45f78e2f6429
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180665
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit f071292a5af10f4718302a1bf9cc9cdc37528225)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180675
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/basic/qa/basic_coverage/test_variant_arg_used_as_obj.bas 
b/basic/qa/basic_coverage/test_variant_arg_used_as_obj.bas
new file mode 100644
index 000000000000..41ac139f639d
--- /dev/null
+++ b/basic/qa/basic_coverage/test_variant_arg_used_as_obj.bas
@@ -0,0 +1,38 @@
+'
+' This file is part of the LibreOffice project.
+'
+' This Source Code Form is subject to the terms of the Mozilla Public
+' License, v. 2.0. If a copy of the MPL was not distributed with this
+' file, You can obtain one at http://mozilla.org/MPL/2.0/.
+'
+
+Option Explicit
+
+Function doUnitTest() As String
+    TestUtil.TestInit
+    verify_VariantArgUsedAsObj
+    doUnitTest = TestUtil.GetResult()
+End Function
+
+Sub verify_VariantArgUsedAsObj
+    On Error GoTo errorHandler
+
+    Dim aResult
+    ' Without the fix, the following line would fail, triggering errorHandler 
reporting
+    ' "91: Object variable not set."
+    aResult = aFuncWithVarArg(0)
+    TestUtil.AssertEqualStrict(aResult, "Integer", "aResult")
+
+    Exit Sub
+errorHandler:
+    TestUtil.ReportErrorHandler("verify_VariantArgUsedAsObj", Err, Error$, Erl)
+End Sub
+
+Function aFuncWithVarArg(arg)
+    ' The 'arg' is implicitly Variant; and its following use as object (after 
a check),
+    ' i.e. accessing its method using dot notation, must not change the 
declaration type
+    If IsObject(arg) Then
+        arg.some_func()
+    End If
+    aFuncWithVarArg = TypeName(arg)
+End Function
diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx
index db7254033e5e..2f0316428ce6 100644
--- a/basic/source/comp/exprtree.cxx
+++ b/basic/source/comp/exprtree.cxx
@@ -333,7 +333,9 @@ std::unique_ptr<SbiExprNode> SbiExpression::Term( const 
KeywordSymbolInfo* pKeyw
             // from 16.12.95 (similar cases possible perhaps?!?)
             if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT )
             {
-                pDef->SetType( SbxOBJECT );
+                // Do not modify the type of procedure arguments
+                if (pDef->GetScope() != SbPARAM)
+                    pDef->SetType(SbxOBJECT);
             }
             else
             {
@@ -352,7 +354,8 @@ std::unique_ptr<SbiExprNode> SbiExpression::Term( const 
KeywordSymbolInfo* pKeyw
     if( bObj )
     {
         // from 8.1.95: Object may also be of the type SbxVARIANT
-        if( pDef->GetType() == SbxVARIANT )
+        // (but do not modify type of procedure arguments)
+        if (pDef->GetType() == SbxVARIANT && pDef->GetScope() != SbPARAM)
             pDef->SetType( SbxOBJECT );
         // if we scan something with point,
         // the type must be SbxOBJECT

Reply via email to