[vala/0.52] codegen: Add and use CCodeConstantIdentifier for accessing constants



commit 71a70664ddd05287f579f0be54cea93f91b5b0e6
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Mon Nov 15 20:43:19 2021 +0100

    codegen: Add and use CCodeConstantIdentifier for accessing constants
    
    If an address to a constant value is required then its identifier needs
    to be used instead of referring to a temporary copy.
    
    Fixes a regression of f1a8f2a4c6771124abd61fd0ebfa991c846575fe
    
    Found by -fsanitize=address

 ccode/Makefile.am                        |  1 +
 ccode/valaccodeconstantidentifier.vala   | 35 ++++++++++++++++++++++++++++++++
 codegen/valaccodebasemodule.vala         |  6 ++++--
 codegen/valaccodememberaccessmodule.vala |  4 +++-
 tests/Makefile.am                        |  1 +
 tests/constants/member-access.vala       | 26 ++++++++++++++++++++++++
 6 files changed, 70 insertions(+), 3 deletions(-)
---
diff --git a/ccode/Makefile.am b/ccode/Makefile.am
index 9ba660760..c87c5dd1d 100644
--- a/ccode/Makefile.am
+++ b/ccode/Makefile.am
@@ -28,6 +28,7 @@ libvalaccode_la_VALASOURCES = \
        valaccodecomment.vala \
        valaccodeconditionalexpression.vala \
        valaccodeconstant.vala \
+       valaccodeconstantidentifier.vala \
        valaccodecontinuestatement.vala \
        valaccodedeclaration.vala \
        valaccodedeclarator.vala \
diff --git a/ccode/valaccodeconstantidentifier.vala b/ccode/valaccodeconstantidentifier.vala
new file mode 100644
index 000000000..0495389f1
--- /dev/null
+++ b/ccode/valaccodeconstantidentifier.vala
@@ -0,0 +1,35 @@
+/* valaccodeconstantidentifier.vala
+ *
+ * Copyright (C) 2021  Rico Tzschichholz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library 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
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Rico Tzschichholz <ricotz ubuntu com>
+ */
+
+using GLib;
+
+/**
+ * Represents a constant identifier in the C code.
+ */
+public class Vala.CCodeConstantIdentifier : CCodeIdentifier {
+       /**
+        * The name of this constant identifier.
+        */
+       public CCodeConstantIdentifier (string name) {
+               base (name);
+       }
+}
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index c65fda753..f032ecab3 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1477,7 +1477,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        }
 
        public static bool is_constant_ccode_expression (CCodeExpression cexpr) {
-               if (cexpr is CCodeConstant) {
+               if (cexpr is CCodeConstant || cexpr is CCodeConstantIdentifier) {
                        return true;
                } else if (cexpr is CCodeCastExpression) {
                        var ccast = (CCodeCastExpression) cexpr;
@@ -6224,7 +6224,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        result.value_type.nullable = false;
                        if (!result.lvalue || !result.value_type.equals (value.value_type)) {
                                result.cvalue = get_implicit_cast_expression (result.cvalue, 
value.value_type, result.value_type, node);
-                               result = (GLibValue) store_temp_value (result, node);
+                               if (!(result.cvalue is CCodeConstantIdentifier)) {
+                                       result = (GLibValue) store_temp_value (result, node);
+                               }
                        }
                        result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, 
result.cvalue);
                        result.lvalue = false;
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index f8161b947..455827b26 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -185,8 +185,10 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                        s = current_method.get_full_name ();
                                }
                                set_cvalue (expr, new CCodeConstant ("\"%s\"".printf (s)));
-                       } else {
+                       } else if (c.type_reference.is_non_null_simple_type ()) {
                                set_cvalue (expr, new CCodeConstant (get_ccode_name (c)));
+                       } else {
+                               set_cvalue (expr, new CCodeConstantIdentifier (get_ccode_name (c)));
                        }
 
                        if (array_type != null) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b08700f11..6a9070d58 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -101,6 +101,7 @@ TESTS = \
        basic-types/bug788775.vala \
        constants/array-type-invalid.test \
        constants/glog.vala \
+       constants/member-access.vala \
        constants/strings.vala \
        namespace/unique.vala \
        arrays/cast-silent-invalid.test \
diff --git a/tests/constants/member-access.vala b/tests/constants/member-access.vala
new file mode 100644
index 000000000..077a36474
--- /dev/null
+++ b/tests/constants/member-access.vala
@@ -0,0 +1,26 @@
+struct Foo {
+       public int i;
+}
+
+const Foo FOO = { 23 };
+const Foo FAZ = { 42 };
+
+class Bar {
+       public unowned Foo? foo;
+
+       public Bar (Foo _foo) {
+               foo = _foo;
+       }
+}
+
+void main () {
+       Bar bar;
+       {
+               bar = new Bar (FOO);
+       }
+       assert (bar.foo.i == 23);
+       {
+               bar.foo = FAZ;
+       }
+       assert (bar.foo.i == 42);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]