diff --git a/esphome/cpp_generator.py b/esphome/cpp_generator.py index da10567f5c..a32cd945d4 100644 --- a/esphome/cpp_generator.py +++ b/esphome/cpp_generator.py @@ -600,7 +600,11 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj": ) # Extract args from the CallExpression and rebuild as placement new call_expr = rhs.base # CallExpression("new Type", args...) - placement_new = CallExpression(f"new({id_.id}) {the_type}", *call_expr.args) + placement_args: list[Expression] = [] + if call_expr.template_args is not None: + placement_args.append(call_expr.template_args) + placement_args.extend(call_expr.args) + placement_new = CallExpression(f"new({id_.id}) {the_type}", *placement_args) CORE.add(ExpressionStatement(placement_new)) else: decl = VariableDeclarationExpression(id_.type, "*", id_, static=True) diff --git a/tests/component_tests/globals/__init__.py b/tests/component_tests/globals/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/component_tests/globals/config/globals_test.yaml b/tests/component_tests/globals/config/globals_test.yaml new file mode 100644 index 0000000000..1d1a9edaa6 --- /dev/null +++ b/tests/component_tests/globals/config/globals_test.yaml @@ -0,0 +1,16 @@ +esphome: + name: test + +esp32: + board: esp32dev + +globals: + - id: my_global_int + type: int + initial_value: "42" + - id: my_global_float + type: float + initial_value: "1.5" + - id: my_global_bool + type: bool + initial_value: "true" diff --git a/tests/component_tests/globals/test_globals.py b/tests/component_tests/globals/test_globals.py new file mode 100644 index 0000000000..3dec3b1615 --- /dev/null +++ b/tests/component_tests/globals/test_globals.py @@ -0,0 +1,27 @@ +"""Tests for the globals component.""" + +from __future__ import annotations + +from collections.abc import Callable +from pathlib import Path + + +def test_globals_placement_new_with_template_args( + generate_main: Callable[[str | Path], str], + component_config_path: Callable[[str], Path], +) -> None: + """Test that globals uses placement new with template arguments preserved.""" + main_cpp = generate_main(component_config_path("globals_test.yaml")) + + # Globals uses Pvariable with Type.new(template_args, initial_value) + # which exercises the template_args preservation in placement new. + assert "static globals::GlobalsComponent *const my_global_int" in main_cpp + assert "PlacementStorage>" in main_cpp + assert "new(my_global_int) globals::GlobalsComponent" in main_cpp + + # Verify initial value is passed as constructor arg + assert "42" in main_cpp + + # Check other globals are also generated + assert "PlacementStorage>" in main_cpp + assert "PlacementStorage>" in main_cpp