]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Use reference-transfer as needed when transforming conditional-expression
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 5 Mar 2026 15:43:36 +0000 (16:43 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Fri, 6 Mar 2026 07:57:39 +0000 (08:57 +0100)
This avoids possible use-after-free exceptions.

Found by -fsanitize=address

Fixes https://gitlab.gnome.org/GNOME/vala/issues/1648

tests/Makefile.am
tests/control-flow/coalesce-reference-transfer.c-expected
tests/semantic/conditional-expression-ownership.c-expected [new file with mode: 0644]
tests/semantic/conditional-expression-ownership.vala [new file with mode: 0644]
tests/semantic/floating-reference.c-expected
vala/valaconditionalexpression.vala

index d7d76f1278b2d46bd20fce1e6b485e77f95b372b..4d238c82f8778f16334b1312c693ed46c8a33b1a 100644 (file)
@@ -1172,6 +1172,7 @@ TESTS = \
        semantic/compare-type-check.vala \
        semantic/conditional-expression-incompatible.test \
        semantic/conditional-expression-no-block.test \
+       semantic/conditional-expression-ownership.vala \
        semantic/constant-extern.test \
        semantic/constant-pointer.test \
        semantic/constant-reassignment-element.test \
index 68f885952aa1623d427a7d6035705b9d30a551af..01ea5744d1bea731d25416b3c3ad9ad71569574c 100644 (file)
@@ -64,6 +64,7 @@ Foo*
 get_foo (gint* i)
 {
        Foo* _tmp0_ = NULL;
+       Foo* _tmp2_;
        Foo* result;
        if (i != NULL) {
                Foo* _tmp1_;
@@ -74,7 +75,10 @@ get_foo (gint* i)
                _foo_free0 (_tmp0_);
                _tmp0_ = NULL;
        }
-       result = _tmp0_;
+       _tmp2_ = _tmp0_;
+       _tmp0_ = NULL;
+       result = _tmp2_;
+       _foo_free0 (_tmp0_);
        return result;
 }
 
diff --git a/tests/semantic/conditional-expression-ownership.c-expected b/tests/semantic/conditional-expression-ownership.c-expected
new file mode 100644 (file)
index 0000000..ddc5638
--- /dev/null
@@ -0,0 +1,101 @@
+/* semantic_conditional_expression_ownership.c generated by valac, the Vala compiler
+ * generated from semantic_conditional_expression_ownership.vala, do not modify */
+
+#include <glib.h>
+
+#if !defined(VALA_STRICT_C)
+#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
+#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
+#elif defined(__clang__) && (__clang_major__ >= 16)
+#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
+#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
+#endif
+#endif
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+static void _vala_main (void);
+
+static void
+_vala_main (void)
+{
+       {
+               gchar c = '\0';
+               gchar* _tmp0_ = NULL;
+               gchar* s = NULL;
+               gchar* _tmp6_;
+               const gchar* _tmp7_;
+               c = '4';
+               if (g_ascii_isalpha (c)) {
+                       gchar* _tmp1_;
+                       _tmp1_ = g_strdup ("?");
+                       _g_free0 (_tmp0_);
+                       _tmp0_ = _tmp1_;
+               } else {
+                       gchar* _tmp2_ = NULL;
+                       gchar* _tmp5_;
+                       if (g_ascii_isdigit (c)) {
+                               gchar* _tmp3_;
+                               _tmp3_ = g_strdup ("7");
+                               _g_free0 (_tmp2_);
+                               _tmp2_ = _tmp3_;
+                       } else {
+                               gchar* _tmp4_;
+                               _tmp4_ = g_strdup_printf ("%c", c);
+                               _g_free0 (_tmp2_);
+                               _tmp2_ = _tmp4_;
+                       }
+                       _tmp5_ = _tmp2_;
+                       _tmp2_ = NULL;
+                       _g_free0 (_tmp0_);
+                       _tmp0_ = _tmp5_;
+                       _g_free0 (_tmp2_);
+               }
+               _tmp6_ = _tmp0_;
+               _tmp0_ = NULL;
+               s = _tmp6_;
+               _tmp7_ = s;
+               _vala_assert (g_strcmp0 (_tmp7_, "7") == 0, "s == \"7\"");
+               _g_free0 (s);
+               _g_free0 (_tmp0_);
+       }
+       {
+               gchar c = '\0';
+               gchar* r = NULL;
+               gchar* _tmp8_;
+               const gchar* _tmp9_ = NULL;
+               const gchar* s = NULL;
+               c = '4';
+               _tmp8_ = g_strdup ("3");
+               r = _tmp8_;
+               if (g_ascii_isalpha (c)) {
+                       _tmp9_ = "?";
+               } else {
+                       const gchar* _tmp10_ = NULL;
+                       if (!g_ascii_isdigit (c)) {
+                               _tmp10_ = "7";
+                       } else {
+                               const gchar* _tmp11_;
+                               _tmp11_ = r;
+                               _tmp10_ = _tmp11_;
+                       }
+                       _tmp9_ = _tmp10_;
+               }
+               s = _tmp9_;
+               _vala_assert (g_strcmp0 (s, "3") == 0, "s == \"3\"");
+               _g_free0 (r);
+       }
+}
+
+int
+main (int argc,
+      char ** argv)
+{
+       _vala_main ();
+       return 0;
+}
+
diff --git a/tests/semantic/conditional-expression-ownership.vala b/tests/semantic/conditional-expression-ownership.vala
new file mode 100644 (file)
index 0000000..ad1f47c
--- /dev/null
@@ -0,0 +1,13 @@
+void main () {
+       {
+               char c = '4';
+               var s = c.isalpha () ? "?" : (c.isdigit () ? "7" : c.to_string ());
+               assert (s == "7");
+       }
+       {
+               char c = '4';
+               string r = "3";
+               unowned var s = c.isalpha () ? "?" : (!c.isdigit () ? "7" : r);
+               assert (s == "3");
+       }
+}
index 6833d930db130adc1222252018f067276780f3dc..1e2f1f7a5eb83ff0f9635c8827610f9a2bed978a 100644 (file)
@@ -59,12 +59,6 @@ get_floating_variant_with_error (GError** error)
        return result;
 }
 
-static gpointer
-_g_variant_ref0 (gpointer self)
-{
-       return self ? g_variant_ref (self) : NULL;
-}
-
 static gchar*
 _variant_get1 (GVariant* value)
 {
@@ -139,7 +133,8 @@ test_variant (void)
                        _g_variant_unref0 (_tmp11_);
                        _tmp11_ = _tmp14_;
                }
-               _tmp15_ = _g_variant_ref0 (_tmp11_);
+               _tmp15_ = _tmp11_;
+               _tmp11_ = NULL;
                variant = _tmp15_;
                _tmp16_ = variant;
                _tmp17_ = G_VARIANT_TYPE_STRING;
index c8bfdbce135d1640f8181887d9c040202e333f5d..491d7db1b225dd955c1a02c6883f5c6acd946f4f 100644 (file)
@@ -218,12 +218,10 @@ public class Vala.ConditionalExpression : Expression {
                true_stmt.check (context);
                false_stmt.check (context);
 
-               var ma = new MemberAccess.simple (local.name, source_reference);
-               ma.formal_target_type = formal_target_type;
-               ma.target_type = target_type;
+               var replace_expr = SemanticAnalyzer.create_temp_access (local, target_type);
 
-               parent_node.replace_expression (this, ma);
-               ma.check (context);
+               parent_node.replace_expression (this, replace_expr);
+               replace_expr.check (context);
 
                return true;
        }