1 //          Copyright Brian Schott (Hackerpilot) 2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 module dscanner.analysis.asm_style;
7 
8 import std.stdio;
9 import dparse.ast;
10 import dparse.lexer;
11 import dscanner.analysis.base;
12 import dscanner.analysis.helpers;
13 import dsymbol.scope_ : Scope;
14 
15 /**
16  * Checks for confusing asm expressions.
17  * See_also: $(LINK https://issues.dlang.org/show_bug.cgi?id=9738)
18  */
19 final class AsmStyleCheck : BaseAnalyzer
20 {
21 	alias visit = BaseAnalyzer.visit;
22 
23 	mixin AnalyzerInfo!"asm_style_check";
24 
25 	this(string fileName, const(Scope)* sc, bool skipTests = false)
26 	{
27 		super(fileName, sc, skipTests);
28 	}
29 
30 	override void visit(const AsmBrExp brExp)
31 	{
32 		if (brExp.asmBrExp !is null && brExp.asmBrExp.asmUnaExp !is null
33 				&& brExp.asmBrExp.asmUnaExp.asmPrimaryExp !is null)
34 		{
35 			addErrorMessage(brExp.line, brExp.column, "dscanner.confusing.brexp",
36 					"This is confusing because it looks like an array index. Rewrite a[1] as [a + 1] to clarify.");
37 		}
38 		brExp.accept(this);
39 	}
40 }
41 
42 unittest
43 {
44 	import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
45 
46 	StaticAnalysisConfig sac = disabledConfig();
47 	sac.asm_style_check = Check.enabled;
48 	assertAnalyzerWarnings(q{
49 		void testAsm()
50 		{
51 			asm
52 			{
53 				mov a, someArray[1]; // [warn]: This is confusing because it looks like an array index. Rewrite a[1] as [a + 1] to clarify.
54 				add near ptr [EAX], 3;
55 			}
56 		}
57 	}}, sac);
58 
59 	stderr.writeln("Unittest for AsmStyleCheck passed.");
60 }