Merge "Revert "Switch to clang-3625443.""
diff --git a/README.md b/README.md
index 8b086df..bc019ae 100644
--- a/README.md
+++ b/README.md
@@ -163,6 +163,10 @@
 }
 ```
 
+See [art/build/art.go](https://android.googlesource.com/platform/art/+/master/build/art.go)
+or [external/llvm/soong/llvm.go](https://android.googlesource.com/platform/external/llvm/+/master/soong/llvm.go)
+for examples of more complex conditionals on product variables or environment variables.
+
 ## Contact
 
 Email android-building@googlegroups.com (external) for any questions, or see
diff --git a/android/config.go b/android/config.go
index 6d28680..3603477 100644
--- a/android/config.go
+++ b/android/config.go
@@ -398,6 +398,10 @@
 	return append([]string(nil), c.ProductVariables.SanitizeDeviceArch...)
 }
 
+func (c *config) EnableCFI() bool {
+	return Bool(c.ProductVariables.EnableCFI)
+}
+
 func (c *config) Android64() bool {
 	for _, t := range c.Targets[Device] {
 		if t.Arch.ArchType.Multilib == "lib64" {
diff --git a/android/variable.go b/android/variable.go
index 271454a..bb84be2 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -124,6 +124,7 @@
 	UseGoma                    *bool `json:",omitempty"`
 	Debuggable                 *bool `json:",omitempty"`
 	Eng                        *bool `json:",omitempty"`
+	EnableCFI                  *bool `json:",omitempty"`
 
 	VendorPath *string `json:",omitempty"`
 
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 380babc..c0be111 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -155,6 +155,7 @@
 
 func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
 	ctx.subAndroidMk(ret, test.binaryDecorator)
+	ret.Class = "NATIVE_TESTS"
 	if Bool(test.Properties.Test_per_src) {
 		ret.SubName = "_" + test.binaryDecorator.Properties.Stem
 	}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 447c5b4..79c86aa 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -136,8 +136,14 @@
 			s.Undefined = boolPtr(true)
 		}
 
-		if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
-			s.Address = boolPtr(true)
+		if found, globalSanitizers = removeFromList("address", globalSanitizers); found {
+			if s.Address == nil {
+				s.Address = boolPtr(true)
+			} else if *s.Address == false {
+				// Coverage w/o address is an error. If globalSanitizers includes both, and the module
+				// disables address, then disable coverage as well.
+				_, globalSanitizers = removeFromList("coverage", globalSanitizers)
+			}
 		}
 
 		if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
@@ -161,6 +167,11 @@
 		}
 	}
 
+	if !ctx.AConfig().EnableCFI() {
+		s.Cfi = nil
+		s.Diag.Cfi = nil
+	}
+
 	if ctx.staticBinary() {
 		s.Address = nil
 		s.Coverage = nil
@@ -302,6 +313,11 @@
 	}
 
 	if Bool(sanitize.Properties.Sanitize.Cfi) {
+		if ctx.Arch().ArchType == android.Arm {
+			// __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp). LLVM is not set up
+			// to do this on a function basis, so force Thumb on the entire module.
+			flags.RequiredInstructionSet = "thumb"
+		}
 		sanitizers = append(sanitizers, "cfi")
 		cfiFlags := []string{"-flto", "-fsanitize=cfi", "-fsanitize-cfi-cross-dso"}
 		flags.CFlags = append(flags.CFlags, cfiFlags...)
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 5a2ac84..5c71742 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -68,6 +68,9 @@
 
 	// List of directories to export generated headers from
 	Export_include_dirs []string
+
+	// list of input files
+	Srcs []string
 }
 
 type generator struct {
@@ -85,7 +88,7 @@
 	outputFiles android.Paths
 }
 
-type taskFunc func(ctx android.ModuleContext) []generateTask
+type taskFunc func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask
 
 type generateTask struct {
 	in  android.Paths
@@ -105,6 +108,7 @@
 }
 
 func (g *generator) DepsMutator(ctx android.BottomUpMutatorContext) {
+	android.ExtractSourcesDeps(ctx, g.properties.Srcs)
 	if g, ok := ctx.Module().(*generator); ok {
 		if len(g.properties.Tools) > 0 {
 			ctx.AddFarVariationDependencies([]blueprint.Variation{
@@ -208,7 +212,8 @@
 	}
 	g.rule = ctx.Rule(pctx, "generator", ruleParams, args...)
 
-	for _, task := range g.tasks(ctx) {
+	srcFiles := ctx.ExpandSources(g.properties.Srcs, nil)
+	for _, task := range g.tasks(ctx, srcFiles) {
 		g.generateSourceFile(ctx, task)
 	}
 }
@@ -244,8 +249,7 @@
 func GenSrcsFactory() (blueprint.Module, []interface{}) {
 	properties := &genSrcsProperties{}
 
-	tasks := func(ctx android.ModuleContext) []generateTask {
-		srcFiles := ctx.ExpandSources(properties.Srcs, nil)
+	tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask {
 		tasks := make([]generateTask, 0, len(srcFiles))
 		for _, in := range srcFiles {
 			tasks = append(tasks, generateTask{
@@ -260,9 +264,6 @@
 }
 
 type genSrcsProperties struct {
-	// list of input files
-	Srcs []string
-
 	// extension that will be substituted for each output file
 	Output_extension string
 }
@@ -270,14 +271,14 @@
 func GenRuleFactory() (blueprint.Module, []interface{}) {
 	properties := &genRuleProperties{}
 
-	tasks := func(ctx android.ModuleContext) []generateTask {
+	tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask {
 		outs := make(android.WritablePaths, len(properties.Out))
 		for i, out := range properties.Out {
 			outs[i] = android.PathForModuleGen(ctx, out)
 		}
 		return []generateTask{
 			{
-				in:  ctx.ExpandSources(properties.Srcs, nil),
+				in:  srcFiles,
 				out: outs,
 			},
 		}
@@ -287,9 +288,6 @@
 }
 
 type genRuleProperties struct {
-	// list of input files
-	Srcs []string
-
 	// names of the output files that will be generated
 	Out []string
 }