diff --git a/Ghidra/Features/SystemEmulation/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java b/Ghidra/Features/SystemEmulation/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java index 0481a12a6e..4ce89004b1 100644 --- a/Ghidra/Features/SystemEmulation/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java +++ b/Ghidra/Features/SystemEmulation/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,6 +16,7 @@ package ghidra.pcode.struct.sub; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; @@ -25,8 +26,7 @@ import org.junit.Before; import org.junit.Test; import ghidra.app.plugin.processors.sleigh.SleighException; -import ghidra.pcode.exec.PcodeUseropLibrary; -import ghidra.pcode.exec.SleighPcodeUseropDefinition; +import ghidra.pcode.exec.*; import ghidra.pcode.struct.StructuredSleigh; import ghidra.program.model.lang.*; import ghidra.program.model.pcode.Varnode; @@ -238,4 +238,16 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest // TODO: Test that the generated code compiles in a slaspec file. // It's rejected for injects because "return" is not valid there. } + + @Test + public void testEmpty() throws Exception { + StructuredSleigh ss = new TestStructuredSleigh() { + @StructuredUserop + public void my_userop() { + } + }; + SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); + PcodeProgram program = myUserop.programFor(null, List.of(), PcodeUseropLibrary.nil()); + assertTrue(program.getCode().isEmpty()); + } } diff --git a/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java b/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java index 29e3348896..c4aab1246b 100644 --- a/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java +++ b/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java @@ -21,6 +21,7 @@ import java.util.stream.Collectors; import ghidra.app.plugin.processors.sleigh.*; import ghidra.app.plugin.processors.sleigh.template.ConstructTpl; +import ghidra.app.plugin.processors.sleigh.template.OpTpl; import ghidra.pcode.utils.MessageFormattingUtils; import ghidra.pcodeCPort.pcoderaw.VarnodeData; import ghidra.pcodeCPort.sleighbase.SleighBase; @@ -149,6 +150,9 @@ public enum SleighProgramCompiler { */ public static ConstructTpl compileTemplate(Language language, PcodeParser parser, String sourceName, String source) { + if (source.isBlank()) { + return new ConstructTpl(new OpTpl[] {}); + } return parser.compilePcode(source, sourceName, 1); } @@ -285,7 +289,8 @@ public enum SleighProgramCompiler { * evaluator p-code program uses its own library as a means of capturing the result; however, * userop libraries are easily composed. It should be easy to add that feature if needed. * - * @param language the languge of the target p-code machine + * @param parser a parser for the given language + * @param language the language of the target p-code machine * @param expression the Sleigh expression to be evaluated * @return a p-code program whose {@link PcodeExpression#evaluate(PcodeExecutor)} method will * evaluate the expression on the given executor and its state.